1 // sol3
2 
3 // The MIT License (MIT)
4 
5 // Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
6 
7 // Permission is hereby granted, free of charge, to any person obtaining a copy of
8 // this software and associated documentation files (the "Software"), to deal in
9 // the Software without restriction, including without limitation the rights to
10 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11 // the Software, and to permit persons to whom the Software is furnished to do so,
12 // subject to the following conditions:
13 
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 
24 #include "sol_test.hpp"
25 
26 #include <catch2/catch.hpp>
27 
28 #include <iostream>
29 
30 struct test { };
31 template <typename T>
32 struct test_t { };
33 
34 namespace muh_namespace {
35 	struct ns_test { };
36 
37 	namespace {
38 		struct ns_anon_test { };
39 	} // namespace
40 } // namespace muh_namespace
41 
42 TEST_CASE("stack/strings", "test that strings can be roundtripped") {
43 	sol::state lua;
44 	sol::stack_guard luasg(lua);
45 
46 	static const char utf8str[]
47 	     = "\xF0\x9F\x8D\x8C\x20\xE6\x99\xA5\x20\x46\x6F\x6F\x20\xC2\xA9\x20\x62\x61\x72\x20\xF0\x9D\x8C\x86\x20\x62\x61\x7A\x20\xE2\x98\x83\x20\x71\x75\x78";
48 	static const char16_t utf16str[] = { 0xD83C,
49 		0xDF4C,
50 		0x20,
51 		0x6665,
52 		0x20,
53 		0x46,
54 		0x6F,
55 		0x6F,
56 		0x20,
57 		0xA9,
58 		0x20,
59 		0x62,
60 		0x61,
61 		0x72,
62 		0x20,
63 		0xD834,
64 		0xDF06,
65 		0x20,
66 		0x62,
67 		0x61,
68 		0x7A,
69 		0x20,
70 		0x2603,
71 		0x20,
72 		0x71,
73 		0x75,
74 		0x78,
75 		0x00 };
76 	static const char32_t utf32str[] = { 0x1F34C,
77 		0x0020,
78 		0x6665,
79 		0x0020,
80 		0x0046,
81 		0x006F,
82 		0x006F,
83 		0x0020,
84 		0x00A9,
85 		0x0020,
86 		0x0062,
87 		0x0061,
88 		0x0072,
89 		0x0020,
90 		0x1D306,
91 		0x0020,
92 		0x0062,
93 		0x0061,
94 		0x007A,
95 		0x0020,
96 		0x2603,
97 		0x0020,
98 		0x0071,
99 		0x0075,
100 		0x0078,
101 		0x00 };
102 #ifdef _WIN32
103 	INFO("win32 widestr");
104 	static const wchar_t widestr[] = { 0xD83C,
105 		0xDF4C,
106 		0x20,
107 		0x6665,
108 		0x20,
109 		0x46,
110 		0x6F,
111 		0x6F,
112 		0x20,
113 		0xA9,
114 		0x20,
115 		0x62,
116 		0x61,
117 		0x72,
118 		0x20,
119 		0xD834,
120 		0xDF06,
121 		0x20,
122 		0x62,
123 		0x61,
124 		0x7A,
125 		0x20,
126 		0x2603,
127 		0x20,
128 		0x71,
129 		0x75,
130 		0x78,
131 		0x00 };
132 #else
133 	INFO("non-windows widestr");
134 	static const wchar_t widestr[] = { 0x1F34C,
135 		0x0020,
136 		0x6665,
137 		0x0020,
138 		0x0046,
139 		0x006F,
140 		0x006F,
141 		0x0020,
142 		0x00A9,
143 		0x0020,
144 		0x0062,
145 		0x0061,
146 		0x0072,
147 		0x0020,
148 		0x1D306,
149 		0x0020,
150 		0x0062,
151 		0x0061,
152 		0x007A,
153 		0x0020,
154 		0x2603,
155 		0x0020,
156 		0x0071,
157 		0x0075,
158 		0x0078,
159 		0x00 };
160 #endif
161 	static const std::string utf8str_s = utf8str;
162 	static const std::u16string utf16str_s = utf16str;
163 	static const std::u32string utf32str_s = utf32str;
164 	static const std::wstring widestr_s = widestr;
165 
166 	INFO("sizeof(wchar_t): " << sizeof(wchar_t));
167 	INFO("sizeof(char16_t): " << sizeof(char16_t));
168 	INFO("sizeof(char32_t): " << sizeof(char32_t));
169 	INFO("utf8str: " << utf8str);
170 	INFO("utf8str_s: " << utf8str_s);
171 
172 	lua["utf8"] = utf8str;
173 	lua["utf16"] = utf16str;
174 	lua["utf32"] = utf32str;
175 	lua["wide"] = widestr;
176 
177 	SECTION("to_utf8") {
178 		std::string utf8_to_utf8 = lua["utf8"];
179 		std::string utf16_to_utf8 = lua["utf16"];
180 		std::string utf32_to_utf8 = lua["utf32"];
181 		std::string wide_to_utf8 = lua["wide"];
182 
183 		REQUIRE(utf8_to_utf8 == utf8str_s);
184 		REQUIRE(utf16_to_utf8 == utf8str_s);
185 		REQUIRE(utf32_to_utf8 == utf8str_s);
186 		REQUIRE(wide_to_utf8 == utf8str_s);
187 	}
188 	SECTION("to_wide") {
189 		std::wstring utf8_to_wide = lua["utf8"];
190 		std::wstring utf16_to_wide = lua["utf16"];
191 		std::wstring utf32_to_wide = lua["utf32"];
192 		std::wstring wide_to_wide = lua["wide"];
193 
194 		REQUIRE(utf8_to_wide == widestr_s);
195 		REQUIRE(utf16_to_wide == widestr_s);
196 		REQUIRE(utf32_to_wide == widestr_s);
197 		REQUIRE(wide_to_wide == widestr_s);
198 	}
199 	SECTION("to_utf16") {
200 		std::u16string utf8_to_utf16 = lua["utf8"];
201 		std::u16string utf16_to_utf16 = lua["utf16"];
202 		std::u16string utf32_to_utf16 = lua["utf32"];
203 		std::u16string wide_to_utf16 = lua["wide"];
204 
205 		REQUIRE(utf8_to_utf16 == utf16str_s);
206 		REQUIRE(utf16_to_utf16 == utf16str_s);
207 		REQUIRE(utf32_to_utf16 == utf16str_s);
208 		REQUIRE(wide_to_utf16 == utf16str_s);
209 	}
210 	SECTION("to_utf32") {
211 		std::u32string utf8_to_utf32 = lua["utf8"];
212 		std::u32string utf16_to_utf32 = lua["utf16"];
213 		std::u32string utf32_to_utf32 = lua["utf32"];
214 		std::u32string wide_to_utf32 = lua["wide"];
215 
216 		REQUIRE(utf8_to_utf32 == utf32str_s);
217 		REQUIRE(utf16_to_utf32 == utf32str_s);
218 		REQUIRE(utf32_to_utf32 == utf32str_s);
219 		REQUIRE(wide_to_utf32 == utf32str_s);
220 	}
221 	SECTION("to_char32_t") {
222 		char32_t utf8_to_char32 = lua["utf8"];
223 		char32_t utf16_to_char32 = lua["utf16"];
224 		char32_t utf32_to_char32 = lua["utf32"];
225 		char32_t wide_to_char32 = lua["wide"];
226 
227 		REQUIRE(utf8_to_char32 == utf32str[0]);
228 		REQUIRE(utf16_to_char32 == utf32str[0]);
229 		REQUIRE(utf32_to_char32 == utf32str[0]);
230 		REQUIRE(wide_to_char32 == utf32str[0]);
231 	}
232 	SECTION("to_char16_t") {
233 		char16_t utf8_to_char16 = lua["utf8"];
234 		char16_t utf16_to_char16 = lua["utf16"];
235 		char16_t utf32_to_char16 = lua["utf32"];
236 		char16_t wide_to_char16 = lua["wide"];
237 
238 		REQUIRE(utf8_to_char16 == utf16str[0]);
239 		REQUIRE(utf16_to_char16 == utf16str[0]);
240 		REQUIRE(utf32_to_char16 == utf16str[0]);
241 		REQUIRE(wide_to_char16 == utf16str[0]);
242 	}
243 	SECTION("to_char") {
244 		char utf8_to_char = lua["utf8"].get<char>();
245 		char utf16_to_char = lua["utf16"].get<char>();
246 		char utf32_to_char = lua["utf32"].get<char>();
247 		char wide_to_char = lua["wide"].get<char>();
248 
249 		REQUIRE(utf8_to_char == utf8str[0]);
250 		REQUIRE(utf16_to_char == utf8str[0]);
251 		REQUIRE(utf32_to_char == utf8str[0]);
252 		REQUIRE(wide_to_char == utf8str[0]);
253 	}
254 }
255 
256 TEST_CASE("detail/demangling", "test some basic demangling cases") {
257 	std::string teststr = sol::detail::short_demangle<test>();
258 	std::string nsteststr = sol::detail::short_demangle<muh_namespace::ns_test>();
259 	std::string nsateststr = sol::detail::short_demangle<muh_namespace::ns_anon_test>();
260 
261 	REQUIRE(teststr == "test");
262 	REQUIRE(nsteststr == "ns_test");
263 	REQUIRE(nsateststr == "ns_anon_test");
264 }
265 
266 TEST_CASE("object/string-pushers", "test some basic string pushers with in_place constructor") {
267 	sol::state lua;
268 
269 	sol::object ocs(lua, sol::in_place, "bark\0bark", 9u);
270 	sol::object os(lua, sol::in_place_type<std::string>, std::string("bark\0bark", 9), 8u);
271 	sol::object osv(lua, sol::in_place_type<sol::string_view>, sol::string_view("woofwoof", 8), 8u);
272 	bool test1 = ocs.as<std::string>() == std::string("bark\0bark", 9);
273 	bool test2 = os.as<std::string>() == std::string("bark\0bar", 8);
274 	bool test3 = osv.as<std::string>() == std::string("woofwoof", 8);
275 	REQUIRE(ocs.get_type() == sol::type::string);
276 	REQUIRE(ocs.is<std::string>());
277 	REQUIRE(ocs.is<sol::string_view>());
278 
279 	REQUIRE(os.get_type() == sol::type::string);
280 	REQUIRE(os.is<std::string>());
281 	REQUIRE(os.is<sol::string_view>());
282 
283 	REQUIRE(osv.get_type() == sol::type::string);
284 	REQUIRE(osv.is<std::string>());
285 	REQUIRE(osv.is<sol::string_view>());
286 
287 	REQUIRE(test1);
288 	REQUIRE(test2);
289 	REQUIRE(test3);
290 }
291 
292 TEST_CASE("strings/non const c strings", "push non const qualified c strings as strings") {
293 	sol::state lua;
294 
295 	char cbark[] = "bark";
296 	char* bark = cbark;
297 	lua["bark"] = bark;
298 	sol::type t = lua["bark"].get_type();
299 	std::string lbark = lua["bark"];
300 
301 	REQUIRE((t == sol::type::string));
302 	REQUIRE((bark == std::string("bark")));
303 }
304