state_test.cpp revision 1.1.1.1 1 // Copyright 2011 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 #include "state.ipp"
30
31 #include <cstring>
32 #include <fstream>
33 #include <iostream>
34 #include <stdexcept>
35
36 #include <atf-c++.hpp>
37 #include <lua.hpp>
38
39 #include "c_gate.hpp"
40 #include "exceptions.hpp"
41 #include "test_utils.hpp"
42
43
44 // A note about the lutok::state tests.
45 //
46 // The methods of lutok::state are, in general, thin wrappers around the
47 // corresponding Lua C API methods. The tests below are simple unit tests that
48 // ensure that these functions just delegate the calls to the Lua library. We
49 // do not intend to test the validity of the methods themselves (that's the
50 // job of the Lua authors). That said, we test those conditions we rely on,
51 // such as the reporting of errors and the default values to the API.
52 //
53 // Lastly, for every test case that stresses a single lutok::state method, we
54 // only call that method directly. All other Lua state manipulation operations
55 // are performed by means of direct calls to the Lua C API. This is to ensure
56 // that the wrapped methods are really talking to Lua.
57
58
59 namespace {
60
61
62 /// Checks if a symbol is available.
63 ///
64 /// \param state The Lua state.
65 /// \param symbol The symbol to check for.
66 ///
67 /// \return True if the symbol is defined, false otherwise.
68 static bool
69 is_available(lutok::state& state, const char* symbol)
70 {
71 luaL_loadstring(raw(state), (std::string("return ") + symbol).c_str());
72 const bool ok = (lua_pcall(raw(state), 0, 1, 0) == 0 &&
73 !lua_isnil(raw(state), -1));
74 lua_pop(raw(state), 1);
75 std::cout << "Symbol " << symbol << (ok ? " found\n" : " not found\n");
76 return ok;
77 }
78
79
80 /// Checks that no modules are present or that only one has been loaded.
81 ///
82 /// \post The test case terminates if there is any module present when expected
83 /// is empty or if there two modules loaded when expected is defined.
84 ///
85 /// \param state The Lua state.
86 /// \param expected The module to expect. Empty if no modules are allowed.
87 static void
88 check_modules(lutok::state& state, const std::string& expected)
89 {
90 std::cout << "Checking loaded modules" <<
91 (expected.empty() ? "" : (" (" + expected + " expected)")) << "\n";
92 ATF_REQUIRE(!((expected == "base") ^ (is_available(state, "assert"))));
93 ATF_REQUIRE(!((expected == "string") ^
94 (is_available(state, "string.byte"))));
95 ATF_REQUIRE(!((expected == "table") ^
96 (is_available(state, "table.concat"))));
97 }
98
99
100 /// A C closure that returns its two integral upvalues.
101 ///
102 /// \post stack(-2) contains the first upvalue.
103 /// \post stack(-1) contains the second upvalue.
104 ///
105 /// \param raw_state The raw Lua state.
106 ///
107 /// \return The number of result values, i.e. 2.
108 static int
109 c_get_upvalues(lua_State* raw_state)
110 {
111 lutok::state state = lutok::state_c_gate::connect(raw_state);
112 const int i1 = lua_tointeger(raw_state, state.upvalue_index(1));
113 const int i2 = lua_tointeger(raw_state, state.upvalue_index(2));
114 lua_pushinteger(raw_state, i1);
115 lua_pushinteger(raw_state, i2);
116 return 2;
117 }
118
119
120 /// A custom C++ multiply function with one of its factors on its closure.
121 ///
122 /// \pre stack(-1) contains the second factor.
123 /// \post stack(-1) contains the product of the two input factors.
124 ///
125 /// \param state The Lua state.
126 ///
127 /// \return The number of result values, i.e. 1.
128 static int
129 cxx_multiply_closure(lutok::state& state)
130 {
131 const int f1 = lua_tointeger(raw(state), lua_upvalueindex(1));
132 const int f2 = lua_tointeger(raw(state), -1);
133 lua_pushinteger(raw(state), f1 * f2);
134 return 1;
135 }
136
137
138 /// A custom C++ integral division function for Lua.
139 ///
140 /// \pre stack(-2) contains the dividend.
141 /// \pre stack(-1) contains the divisor.
142 /// \post stack(-2) contains the quotient of the division.
143 /// \post stack(-1) contains the remainder of the division.
144 ///
145 /// \param state The Lua state.
146 ///
147 /// \return The number of result values, i.e. 1.
148 ///
149 /// \throw std::runtime_error If the divisor is zero.
150 /// \throw std::string If the dividend or the divisor are negative. This is an
151 /// exception not derived from std::exception on purpose to ensure that the
152 /// C++ wrapping correctly captures any exception regardless of its type.
153 static int
154 cxx_divide(lutok::state& state)
155 {
156 const int dividend = state.to_integer(-2);
157 const int divisor = state.to_integer(-1);
158 if (divisor == 0)
159 throw std::runtime_error("Divisor is 0");
160 if (dividend < 0 || divisor < 0)
161 throw std::string("Cannot divide negative numbers");
162 state.push_integer(dividend / divisor);
163 state.push_integer(dividend % divisor);
164 return 2;
165 }
166
167
168 /// A Lua function that raises a very long error message.
169 ///
170 /// \pre stack(-1) contains the length of the message to construct.
171 ///
172 /// \param state The Lua state.
173 ///
174 /// \return Never returns.
175 ///
176 /// \throw std::runtime_error Unconditionally, with an error message formed by
177 /// the repetition of 'A' as many times as requested.
178 static int
179 raise_long_error(lutok::state& state)
180 {
181 const int length = state.to_integer();
182 throw std::runtime_error(std::string(length, 'A').c_str());
183 }
184
185
186 } // anonymous namespace
187
188
189 ATF_TEST_CASE_WITHOUT_HEAD(close);
190 ATF_TEST_CASE_BODY(close)
191 {
192 lutok::state state;
193 state.close();
194 // The destructor for state will run now. If it does a second close, we may
195 // crash, so let's see if we don't.
196 }
197
198
199 ATF_TEST_CASE_WITHOUT_HEAD(get_global__ok);
200 ATF_TEST_CASE_BODY(get_global__ok)
201 {
202 lutok::state state;
203 ATF_REQUIRE(luaL_dostring(raw(state), "test_variable = 3") == 0);
204 state.get_global("test_variable");
205 ATF_REQUIRE(lua_isnumber(raw(state), -1));
206 lua_pop(raw(state), 1);
207 }
208
209
210 ATF_TEST_CASE_WITHOUT_HEAD(get_global__fail);
211 ATF_TEST_CASE_BODY(get_global__fail)
212 {
213 lutok::state state;
214 lua_pushinteger(raw(state), 3);
215 lua_replace(raw(state), LUA_GLOBALSINDEX);
216 REQUIRE_API_ERROR("lua_getglobal", state.get_global("test_variable"));
217 }
218
219
220 ATF_TEST_CASE_WITHOUT_HEAD(get_global__undefined);
221 ATF_TEST_CASE_BODY(get_global__undefined)
222 {
223 lutok::state state;
224 state.get_global("test_variable");
225 ATF_REQUIRE(lua_isnil(raw(state), -1));
226 lua_pop(raw(state), 1);
227 }
228
229
230 ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__ok);
231 ATF_TEST_CASE_BODY(get_metafield__ok)
232 {
233 lutok::state state;
234 luaL_openlibs(raw(state));
235 ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
236 "t = {}; setmetatable(t, meta)") == 0);
237 lua_getglobal(raw(state), "t");
238 ATF_REQUIRE(state.get_metafield(-1, "foo"));
239 ATF_REQUIRE(lua_isnumber(raw(state), -1));
240 ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
241 lua_pop(raw(state), 2);
242 }
243
244
245 ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__undefined);
246 ATF_TEST_CASE_BODY(get_metafield__undefined)
247 {
248 lutok::state state;
249 luaL_openlibs(raw(state));
250 ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
251 "t = {}; setmetatable(t, meta)") == 0);
252 lua_getglobal(raw(state), "t");
253 ATF_REQUIRE(!state.get_metafield(-1, "bar"));
254 lua_pop(raw(state), 1);
255 }
256
257
258 ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__top);
259 ATF_TEST_CASE_BODY(get_metatable__top)
260 {
261 lutok::state state;
262 luaL_openlibs(raw(state));
263 ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
264 "t = {}; setmetatable(t, meta)") == 0);
265 lua_getglobal(raw(state), "t");
266 ATF_REQUIRE(state.get_metatable());
267 ATF_REQUIRE(lua_istable(raw(state), -1));
268 lua_pushstring(raw(state), "foo");
269 lua_gettable(raw(state), -2);
270 ATF_REQUIRE(lua_isnumber(raw(state), -1));
271 ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
272 lua_pop(raw(state), 3);
273 }
274
275
276 ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__explicit);
277 ATF_TEST_CASE_BODY(get_metatable__explicit)
278 {
279 lutok::state state;
280 luaL_openlibs(raw(state));
281 ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
282 "t = {}; setmetatable(t, meta)") == 0);
283 lua_getglobal(raw(state), "t");
284 lua_pushinteger(raw(state), 5555);
285 ATF_REQUIRE(state.get_metatable(-2));
286 ATF_REQUIRE(lua_istable(raw(state), -1));
287 lua_pushstring(raw(state), "foo");
288 lua_gettable(raw(state), -2);
289 ATF_REQUIRE(lua_isnumber(raw(state), -1));
290 ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
291 lua_pop(raw(state), 4);
292 }
293
294
295 ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__undefined);
296 ATF_TEST_CASE_BODY(get_metatable__undefined)
297 {
298 lutok::state state;
299 ATF_REQUIRE(luaL_dostring(raw(state), "t = {}") == 0);
300 lua_getglobal(raw(state), "t");
301 ATF_REQUIRE(!state.get_metatable(-1));
302 lua_pop(raw(state), 1);
303 }
304
305
306 ATF_TEST_CASE_WITHOUT_HEAD(get_table__ok);
307 ATF_TEST_CASE_BODY(get_table__ok)
308 {
309 lutok::state state;
310 ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
311 lua_getglobal(raw(state), "t");
312 lua_pushstring(raw(state), "bar");
313 state.get_table();
314 ATF_REQUIRE(lua_isnumber(raw(state), -1));
315 ATF_REQUIRE_EQ(234, lua_tointeger(raw(state), -1));
316 lua_pop(raw(state), 2);
317 }
318
319
320 ATF_TEST_CASE_WITHOUT_HEAD(get_table__nil);
321 ATF_TEST_CASE_BODY(get_table__nil)
322 {
323 lutok::state state;
324 lua_pushnil(raw(state));
325 lua_pushinteger(raw(state), 1);
326 REQUIRE_API_ERROR("lua_gettable", state.get_table());
327 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
328 lua_pop(raw(state), 2);
329 }
330
331
332 ATF_TEST_CASE_WITHOUT_HEAD(get_table__unknown_index);
333 ATF_TEST_CASE_BODY(get_table__unknown_index)
334 {
335 lutok::state state;
336 ATF_REQUIRE(luaL_dostring(raw(state),
337 "the_table = { foo = 1, bar = 2 }") == 0);
338 lua_getglobal(raw(state), "the_table");
339 lua_pushstring(raw(state), "baz");
340 state.get_table();
341 ATF_REQUIRE(lua_isnil(raw(state), -1));
342 lua_pop(raw(state), 2);
343 }
344
345
346 ATF_TEST_CASE_WITHOUT_HEAD(get_top);
347 ATF_TEST_CASE_BODY(get_top)
348 {
349 lutok::state state;
350 ATF_REQUIRE_EQ(0, state.get_top());
351 lua_pushinteger(raw(state), 3);
352 ATF_REQUIRE_EQ(1, state.get_top());
353 lua_pushinteger(raw(state), 3);
354 ATF_REQUIRE_EQ(2, state.get_top());
355 lua_pop(raw(state), 2);
356 }
357
358
359 ATF_TEST_CASE_WITHOUT_HEAD(globals_index);
360 ATF_TEST_CASE_BODY(globals_index)
361 {
362 lutok::state state;
363 ATF_REQUIRE(luaL_dostring(raw(state), "global_variable = 'hello'") == 0);
364 lua_pushvalue(raw(state), lutok::globals_index);
365 lua_pushstring(raw(state), "global_variable");
366 lua_gettable(raw(state), -2);
367 ATF_REQUIRE(lua_isstring(raw(state), -1));
368 ATF_REQUIRE(std::strcmp("hello", lua_tostring(raw(state), -1)) == 0);
369 lua_pop(raw(state), 2);
370 }
371
372
373 ATF_TEST_CASE_WITHOUT_HEAD(insert);
374 ATF_TEST_CASE_BODY(insert)
375 {
376 lutok::state state;
377 lua_pushinteger(raw(state), 1);
378 lua_pushinteger(raw(state), 2);
379 lua_pushinteger(raw(state), 3);
380 lua_pushinteger(raw(state), 4);
381 state.insert(-3);
382 ATF_REQUIRE_EQ(3, lua_tointeger(raw(state), -1));
383 ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
384 ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -3));
385 ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -4));
386 lua_pop(raw(state), 4);
387 }
388
389
390 ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__empty);
391 ATF_TEST_CASE_BODY(is_boolean__empty)
392 {
393 lutok::state state;
394 ATF_REQUIRE(!state.is_boolean());
395 }
396
397
398 ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__top);
399 ATF_TEST_CASE_BODY(is_boolean__top)
400 {
401 lutok::state state;
402 lua_pushnil(raw(state));
403 ATF_REQUIRE(!state.is_boolean());
404 lua_pushboolean(raw(state), 1);
405 ATF_REQUIRE(state.is_boolean());
406 lua_pop(raw(state), 2);
407 }
408
409
410 ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__explicit);
411 ATF_TEST_CASE_BODY(is_boolean__explicit)
412 {
413 lutok::state state;
414 lua_pushboolean(raw(state), 1);
415 ATF_REQUIRE(state.is_boolean(-1));
416 lua_pushinteger(raw(state), 5);
417 ATF_REQUIRE(!state.is_boolean(-1));
418 ATF_REQUIRE(state.is_boolean(-2));
419 lua_pop(raw(state), 2);
420 }
421
422
423 ATF_TEST_CASE_WITHOUT_HEAD(is_function__empty);
424 ATF_TEST_CASE_BODY(is_function__empty)
425 {
426 lutok::state state;
427 ATF_REQUIRE(!state.is_function());
428 }
429
430
431 ATF_TEST_CASE_WITHOUT_HEAD(is_function__top);
432 ATF_TEST_CASE_BODY(is_function__top)
433 {
434 lutok::state state;
435 luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
436
437 lua_pushnil(raw(state));
438 ATF_REQUIRE(!state.is_function());
439 lua_getglobal(raw(state), "my_func");
440 ATF_REQUIRE(state.is_function());
441 lua_pop(raw(state), 2);
442 }
443
444
445 ATF_TEST_CASE_WITHOUT_HEAD(is_function__explicit);
446 ATF_TEST_CASE_BODY(is_function__explicit)
447 {
448 lutok::state state;
449 luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
450
451 lua_getglobal(raw(state), "my_func");
452 ATF_REQUIRE(state.is_function(-1));
453 lua_pushinteger(raw(state), 5);
454 ATF_REQUIRE(!state.is_function(-1));
455 ATF_REQUIRE(state.is_function(-2));
456 lua_pop(raw(state), 2);
457 }
458
459
460 ATF_TEST_CASE_WITHOUT_HEAD(is_nil__empty);
461 ATF_TEST_CASE_BODY(is_nil__empty)
462 {
463 lutok::state state;
464 ATF_REQUIRE(state.is_nil());
465 }
466
467
468 ATF_TEST_CASE_WITHOUT_HEAD(is_nil__top);
469 ATF_TEST_CASE_BODY(is_nil__top)
470 {
471 lutok::state state;
472 lua_pushnil(raw(state));
473 ATF_REQUIRE(state.is_nil());
474 lua_pushinteger(raw(state), 5);
475 ATF_REQUIRE(!state.is_nil());
476 lua_pop(raw(state), 2);
477 }
478
479
480 ATF_TEST_CASE_WITHOUT_HEAD(is_nil__explicit);
481 ATF_TEST_CASE_BODY(is_nil__explicit)
482 {
483 lutok::state state;
484 lua_pushnil(raw(state));
485 ATF_REQUIRE(state.is_nil(-1));
486 lua_pushinteger(raw(state), 5);
487 ATF_REQUIRE(!state.is_nil(-1));
488 ATF_REQUIRE(state.is_nil(-2));
489 lua_pop(raw(state), 2);
490 }
491
492
493 ATF_TEST_CASE_WITHOUT_HEAD(is_number__empty);
494 ATF_TEST_CASE_BODY(is_number__empty)
495 {
496 lutok::state state;
497 ATF_REQUIRE(!state.is_number());
498 }
499
500
501 ATF_TEST_CASE_WITHOUT_HEAD(is_number__top);
502 ATF_TEST_CASE_BODY(is_number__top)
503 {
504 lutok::state state;
505 lua_pushnil(raw(state));
506 ATF_REQUIRE(!state.is_number());
507 lua_pushinteger(raw(state), 5);
508 ATF_REQUIRE(state.is_number());
509 lua_pop(raw(state), 2);
510 }
511
512
513 ATF_TEST_CASE_WITHOUT_HEAD(is_number__explicit);
514 ATF_TEST_CASE_BODY(is_number__explicit)
515 {
516 lutok::state state;
517 lua_pushnil(raw(state));
518 ATF_REQUIRE(!state.is_number(-1));
519 lua_pushinteger(raw(state), 5);
520 ATF_REQUIRE(state.is_number(-1));
521 ATF_REQUIRE(!state.is_number(-2));
522 lua_pop(raw(state), 2);
523 }
524
525
526 ATF_TEST_CASE_WITHOUT_HEAD(is_string__empty);
527 ATF_TEST_CASE_BODY(is_string__empty)
528 {
529 lutok::state state;
530 ATF_REQUIRE(!state.is_string());
531 }
532
533
534 ATF_TEST_CASE_WITHOUT_HEAD(is_string__top);
535 ATF_TEST_CASE_BODY(is_string__top)
536 {
537 lutok::state state;
538 lua_pushnil(raw(state));
539 ATF_REQUIRE(!state.is_string());
540 lua_pushinteger(raw(state), 3);
541 ATF_REQUIRE(state.is_string());
542 lua_pushstring(raw(state), "foo");
543 ATF_REQUIRE(state.is_string());
544 lua_pop(raw(state), 3);
545 }
546
547
548 ATF_TEST_CASE_WITHOUT_HEAD(is_string__explicit);
549 ATF_TEST_CASE_BODY(is_string__explicit)
550 {
551 lutok::state state;
552 lua_pushinteger(raw(state), 3);
553 ATF_REQUIRE(state.is_string(-1));
554 lua_pushnil(raw(state));
555 ATF_REQUIRE(!state.is_string(-1));
556 ATF_REQUIRE(state.is_string(-2));
557 lua_pushstring(raw(state), "foo");
558 ATF_REQUIRE(state.is_string(-1));
559 ATF_REQUIRE(!state.is_string(-2));
560 ATF_REQUIRE(state.is_string(-3));
561 lua_pop(raw(state), 3);
562 }
563
564
565 ATF_TEST_CASE_WITHOUT_HEAD(is_table__empty);
566 ATF_TEST_CASE_BODY(is_table__empty)
567 {
568 lutok::state state;
569 ATF_REQUIRE(!state.is_table());
570 }
571
572
573 ATF_TEST_CASE_WITHOUT_HEAD(is_table__top);
574 ATF_TEST_CASE_BODY(is_table__top)
575 {
576 lutok::state state;
577 luaL_dostring(raw(state), "t = {3, 4, 5}");
578
579 lua_pushstring(raw(state), "foo");
580 ATF_REQUIRE(!state.is_table());
581 lua_getglobal(raw(state), "t");
582 ATF_REQUIRE(state.is_table());
583 lua_pop(raw(state), 2);
584 }
585
586
587 ATF_TEST_CASE_WITHOUT_HEAD(is_table__explicit);
588 ATF_TEST_CASE_BODY(is_table__explicit)
589 {
590 lutok::state state;
591 luaL_dostring(raw(state), "t = {3, 4, 5}");
592
593 lua_pushstring(raw(state), "foo");
594 ATF_REQUIRE(!state.is_table(-1));
595 lua_getglobal(raw(state), "t");
596 ATF_REQUIRE(state.is_table(-1));
597 ATF_REQUIRE(!state.is_table(-2));
598 lua_pop(raw(state), 2);
599 }
600
601
602 ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__empty);
603 ATF_TEST_CASE_BODY(is_userdata__empty)
604 {
605 lutok::state state;
606 ATF_REQUIRE(!state.is_userdata());
607 }
608
609
610 ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__top);
611 ATF_TEST_CASE_BODY(is_userdata__top)
612 {
613 lutok::state state;
614
615 lua_pushstring(raw(state), "foo");
616 ATF_REQUIRE(!state.is_userdata());
617 lua_newuserdata(raw(state), 1234);
618 ATF_REQUIRE(state.is_userdata());
619 lua_pop(raw(state), 2);
620 }
621
622
623 ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__explicit);
624 ATF_TEST_CASE_BODY(is_userdata__explicit)
625 {
626 lutok::state state;
627
628 lua_pushstring(raw(state), "foo");
629 ATF_REQUIRE(!state.is_userdata(-1));
630 lua_newuserdata(raw(state), 543);
631 ATF_REQUIRE(state.is_userdata(-1));
632 ATF_REQUIRE(!state.is_userdata(-2));
633 lua_pop(raw(state), 2);
634 }
635
636
637 ATF_TEST_CASE_WITHOUT_HEAD(load_file__ok);
638 ATF_TEST_CASE_BODY(load_file__ok)
639 {
640 std::ofstream output("test.lua");
641 output << "in_the_file = \"oh yes\"\n";
642 output.close();
643
644 lutok::state state;
645 state.load_file("test.lua");
646 ATF_REQUIRE(lua_pcall(raw(state), 0, 0, 0) == 0);
647 lua_getglobal(raw(state), "in_the_file");
648 ATF_REQUIRE(std::strcmp("oh yes", lua_tostring(raw(state), -1)) == 0);
649 lua_pop(raw(state), 1);
650 }
651
652
653 ATF_TEST_CASE_WITHOUT_HEAD(load_file__api_error);
654 ATF_TEST_CASE_BODY(load_file__api_error)
655 {
656 std::ofstream output("test.lua");
657 output << "I have a bad syntax! Wohoo!\n";
658 output.close();
659
660 lutok::state state;
661 REQUIRE_API_ERROR("luaL_loadfile", state.load_file("test.lua"));
662 }
663
664
665 ATF_TEST_CASE_WITHOUT_HEAD(load_file__file_not_found_error);
666 ATF_TEST_CASE_BODY(load_file__file_not_found_error)
667 {
668 lutok::state state;
669 ATF_REQUIRE_THROW_RE(lutok::file_not_found_error, "missing.lua",
670 state.load_file("missing.lua"));
671 }
672
673
674 ATF_TEST_CASE_WITHOUT_HEAD(load_string__ok);
675 ATF_TEST_CASE_BODY(load_string__ok)
676 {
677 lutok::state state;
678 state.load_string("return 2 + 3");
679 ATF_REQUIRE(lua_pcall(raw(state), 0, 1, 0) == 0);
680 ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -1));
681 lua_pop(raw(state), 1);
682 }
683
684
685 ATF_TEST_CASE_WITHOUT_HEAD(load_string__fail);
686 ATF_TEST_CASE_BODY(load_string__fail)
687 {
688 lutok::state state;
689 REQUIRE_API_ERROR("luaL_loadstring", state.load_string("-"));
690 }
691
692
693 ATF_TEST_CASE_WITHOUT_HEAD(new_table);
694 ATF_TEST_CASE_BODY(new_table)
695 {
696 lutok::state state;
697 state.new_table();
698 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
699 ATF_REQUIRE(lua_istable(raw(state), -1));
700 lua_pop(raw(state), 1);
701 }
702
703
704 ATF_TEST_CASE_WITHOUT_HEAD(new_userdata);
705 ATF_TEST_CASE_BODY(new_userdata)
706 {
707 lutok::state state;
708 int* pointer = state.new_userdata< int >();
709 *pointer = 1234;
710 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
711 ATF_REQUIRE(lua_isuserdata(raw(state), -1));
712 lua_pop(raw(state), 1);
713 }
714
715
716 ATF_TEST_CASE_WITHOUT_HEAD(next__empty);
717 ATF_TEST_CASE_BODY(next__empty)
718 {
719 lutok::state state;
720 luaL_dostring(raw(state), "t = {}");
721
722 lua_getglobal(raw(state), "t");
723 lua_pushstring(raw(state), "this is a dummy value");
724 lua_pushnil(raw(state));
725 ATF_REQUIRE(!state.next(-3));
726 lua_pop(raw(state), 2);
727 }
728
729
730 ATF_TEST_CASE_WITHOUT_HEAD(next__many);
731 ATF_TEST_CASE_BODY(next__many)
732 {
733 lutok::state state;
734 luaL_dostring(raw(state), "t = {}; t[1] = 100; t[2] = 200");
735
736 lua_getglobal(raw(state), "t");
737 lua_pushnil(raw(state));
738
739 ATF_REQUIRE(state.next());
740 ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
741 ATF_REQUIRE(lua_isnumber(raw(state), -2));
742 ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -2));
743 ATF_REQUIRE(lua_isnumber(raw(state), -1));
744 ATF_REQUIRE_EQ(100, lua_tointeger(raw(state), -1));
745 lua_pop(raw(state), 1);
746
747 ATF_REQUIRE(state.next());
748 ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
749 ATF_REQUIRE(lua_isnumber(raw(state), -2));
750 ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
751 ATF_REQUIRE(lua_isnumber(raw(state), -1));
752 ATF_REQUIRE_EQ(200, lua_tointeger(raw(state), -1));
753 lua_pop(raw(state), 1);
754
755 ATF_REQUIRE(!state.next());
756 lua_pop(raw(state), 1);
757 }
758
759
760 ATF_TEST_CASE_WITHOUT_HEAD(open_base);
761 ATF_TEST_CASE_BODY(open_base)
762 {
763 lutok::state state;
764 check_modules(state, "");
765 state.open_base();
766 check_modules(state, "base");
767 }
768
769
770 ATF_TEST_CASE_WITHOUT_HEAD(open_string);
771 ATF_TEST_CASE_BODY(open_string)
772 {
773 lutok::state state;
774 check_modules(state, "");
775 state.open_string();
776 check_modules(state, "string");
777 }
778
779
780 ATF_TEST_CASE_WITHOUT_HEAD(open_table);
781 ATF_TEST_CASE_BODY(open_table)
782 {
783 lutok::state state;
784 check_modules(state, "");
785 state.open_table();
786 check_modules(state, "table");
787 }
788
789
790 ATF_TEST_CASE_WITHOUT_HEAD(pcall__ok);
791 ATF_TEST_CASE_BODY(pcall__ok)
792 {
793 lutok::state state;
794 luaL_loadstring(raw(state), "function mul(a, b) return a * b; end");
795 state.pcall(0, 0, 0);
796 lua_getfield(raw(state), LUA_GLOBALSINDEX, "mul");
797 lua_pushinteger(raw(state), 3);
798 lua_pushinteger(raw(state), 5);
799 state.pcall(2, 1, 0);
800 ATF_REQUIRE_EQ(15, lua_tointeger(raw(state), -1));
801 lua_pop(raw(state), 1);
802 }
803
804
805 ATF_TEST_CASE_WITHOUT_HEAD(pcall__fail);
806 ATF_TEST_CASE_BODY(pcall__fail)
807 {
808 lutok::state state;
809 lua_pushnil(raw(state));
810 REQUIRE_API_ERROR("lua_pcall", state.pcall(0, 0, 0));
811 }
812
813
814 ATF_TEST_CASE_WITHOUT_HEAD(pop__one);
815 ATF_TEST_CASE_BODY(pop__one)
816 {
817 lutok::state state;
818 lua_pushinteger(raw(state), 10);
819 lua_pushinteger(raw(state), 20);
820 lua_pushinteger(raw(state), 30);
821 state.pop(1);
822 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
823 ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
824 lua_pop(raw(state), 2);
825 }
826
827
828 ATF_TEST_CASE_WITHOUT_HEAD(pop__many);
829 ATF_TEST_CASE_BODY(pop__many)
830 {
831 lutok::state state;
832 lua_pushinteger(raw(state), 10);
833 lua_pushinteger(raw(state), 20);
834 lua_pushinteger(raw(state), 30);
835 state.pop(2);
836 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
837 ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
838 lua_pop(raw(state), 1);
839 }
840
841
842 ATF_TEST_CASE_WITHOUT_HEAD(push_boolean);
843 ATF_TEST_CASE_BODY(push_boolean)
844 {
845 lutok::state state;
846 state.push_boolean(true);
847 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
848 ATF_REQUIRE(lua_toboolean(raw(state), -1));
849 state.push_boolean(false);
850 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
851 ATF_REQUIRE(!lua_toboolean(raw(state), -1));
852 ATF_REQUIRE(lua_toboolean(raw(state), -2));
853 lua_pop(raw(state), 2);
854 }
855
856
857 ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_closure);
858 ATF_TEST_CASE_BODY(push_cxx_closure)
859 {
860 lutok::state state;
861 state.push_integer(15);
862 state.push_cxx_closure(cxx_multiply_closure, 1);
863 lua_setglobal(raw(state), "cxx_multiply_closure");
864
865 ATF_REQUIRE(luaL_dostring(raw(state),
866 "return cxx_multiply_closure(10)") == 0);
867 ATF_REQUIRE_EQ(150, lua_tointeger(raw(state), -1));
868 lua_pop(raw(state), 1);
869 }
870
871
872 ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__ok);
873 ATF_TEST_CASE_BODY(push_cxx_function__ok)
874 {
875 lutok::state state;
876 state.push_cxx_function(cxx_divide);
877 lua_setglobal(raw(state), "cxx_divide");
878
879 ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(17, 3)") == 0);
880 ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -2));
881 ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -1));
882 lua_pop(raw(state), 2);
883 }
884
885
886 ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_exception);
887 ATF_TEST_CASE_BODY(push_cxx_function__fail_exception)
888 {
889 lutok::state state;
890 state.push_cxx_function(cxx_divide);
891 lua_setglobal(raw(state), "cxx_divide");
892
893 ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(15, 0)") != 0);
894 ATF_REQUIRE_MATCH("Divisor is 0", lua_tostring(raw(state), -1));
895 lua_pop(raw(state), 1);
896 }
897
898
899 ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_anything);
900 ATF_TEST_CASE_BODY(push_cxx_function__fail_anything)
901 {
902 lutok::state state;
903 state.push_cxx_function(cxx_divide);
904 lua_setglobal(raw(state), "cxx_divide");
905
906 ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(-3, -1)") != 0);
907 ATF_REQUIRE_MATCH("Unhandled exception", lua_tostring(raw(state), -1));
908 lua_pop(raw(state), 1);
909 }
910
911
912 ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_overflow);
913 ATF_TEST_CASE_BODY(push_cxx_function__fail_overflow)
914 {
915 lutok::state state;
916 state.push_cxx_function(raise_long_error);
917 lua_setglobal(raw(state), "fail");
918
919 ATF_REQUIRE(luaL_dostring(raw(state), "return fail(900)") != 0);
920 ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
921 lua_pop(raw(state), 1);
922
923 ATF_REQUIRE(luaL_dostring(raw(state), "return fail(8192)") != 0);
924 ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
925 lua_pop(raw(state), 1);
926 }
927
928
929 ATF_TEST_CASE_WITHOUT_HEAD(push_integer);
930 ATF_TEST_CASE_BODY(push_integer)
931 {
932 lutok::state state;
933 state.push_integer(12);
934 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
935 ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -1));
936 state.push_integer(34);
937 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
938 ATF_REQUIRE_EQ(34, lua_tointeger(raw(state), -1));
939 ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -2));
940 lua_pop(raw(state), 2);
941 }
942
943
944 ATF_TEST_CASE_WITHOUT_HEAD(push_nil);
945 ATF_TEST_CASE_BODY(push_nil)
946 {
947 lutok::state state;
948 state.push_nil();
949 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
950 ATF_REQUIRE(lua_isnil(raw(state), -1));
951 state.push_integer(34);
952 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
953 ATF_REQUIRE(!lua_isnil(raw(state), -1));
954 ATF_REQUIRE(lua_isnil(raw(state), -2));
955 lua_pop(raw(state), 2);
956 }
957
958
959 ATF_TEST_CASE_WITHOUT_HEAD(push_string);
960 ATF_TEST_CASE_BODY(push_string)
961 {
962 lutok::state state;
963
964 {
965 std::string str = "first";
966 state.push_string(str);
967 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
968 ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -1));
969 str = "second";
970 state.push_string(str);
971 }
972 ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
973 ATF_REQUIRE_EQ(std::string("second"), lua_tostring(raw(state), -1));
974 ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -2));
975 lua_pop(raw(state), 2);
976 }
977
978
979 ATF_TEST_CASE_WITHOUT_HEAD(push_value__top);
980 ATF_TEST_CASE_BODY(push_value__top)
981 {
982 lutok::state state;
983
984 lua_pushinteger(raw(state), 10);
985 lua_pushinteger(raw(state), 20);
986 state.push_value();
987 ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
988 ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
989 ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
990 ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
991 lua_pop(raw(state), 3);
992 }
993
994
995 ATF_TEST_CASE_WITHOUT_HEAD(push_value__explicit);
996 ATF_TEST_CASE_BODY(push_value__explicit)
997 {
998 lutok::state state;
999
1000 lua_pushinteger(raw(state), 10);
1001 lua_pushinteger(raw(state), 20);
1002 state.push_value(-2);
1003 ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
1004 ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
1005 ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
1006 ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
1007 lua_pop(raw(state), 3);
1008 }
1009
1010
1011 ATF_TEST_CASE_WITHOUT_HEAD(raw_get__top);
1012 ATF_TEST_CASE_BODY(raw_get__top)
1013 {
1014 lutok::state state;
1015
1016 luaL_openlibs(raw(state));
1017 ATF_REQUIRE(luaL_dostring(
1018 raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
1019 lua_getglobal(raw(state), "t");
1020 lua_pushstring(raw(state), "foo");
1021 state.raw_get();
1022 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1023 ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
1024 lua_pop(raw(state), 2);
1025 }
1026
1027
1028 ATF_TEST_CASE_WITHOUT_HEAD(raw_get__explicit);
1029 ATF_TEST_CASE_BODY(raw_get__explicit)
1030 {
1031 lutok::state state;
1032
1033 luaL_openlibs(raw(state));
1034 ATF_REQUIRE(luaL_dostring(
1035 raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
1036 lua_getglobal(raw(state), "t");
1037 lua_pushinteger(raw(state), 9876);
1038 lua_pushstring(raw(state), "foo");
1039 state.raw_get(-3);
1040 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1041 ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
1042 ATF_REQUIRE_EQ(9876, lua_tointeger(raw(state), -2));
1043 lua_pop(raw(state), 3);
1044 }
1045
1046
1047 ATF_TEST_CASE_WITHOUT_HEAD(raw_set__top);
1048 ATF_TEST_CASE_BODY(raw_set__top)
1049 {
1050 lutok::state state;
1051
1052 luaL_openlibs(raw(state));
1053 ATF_REQUIRE(luaL_dostring(
1054 raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
1055 lua_getglobal(raw(state), "t");
1056 lua_pushstring(raw(state), "foo");
1057 lua_pushinteger(raw(state), 345);
1058 state.raw_set();
1059 ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
1060 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1061 ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
1062 lua_pop(raw(state), 2);
1063 }
1064
1065
1066 ATF_TEST_CASE_WITHOUT_HEAD(raw_set__explicit);
1067 ATF_TEST_CASE_BODY(raw_set__explicit)
1068 {
1069 lutok::state state;
1070
1071 luaL_openlibs(raw(state));
1072 ATF_REQUIRE(luaL_dostring(
1073 raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
1074 lua_getglobal(raw(state), "t");
1075 lua_pushinteger(raw(state), 876);
1076 lua_pushstring(raw(state), "foo");
1077 lua_pushinteger(raw(state), 345);
1078 state.raw_set(-4);
1079 ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
1080 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1081 ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
1082 ATF_REQUIRE_EQ(876, lua_tointeger(raw(state), -2));
1083 lua_pop(raw(state), 3);
1084 }
1085
1086
1087 ATF_TEST_CASE_WITHOUT_HEAD(set_global__ok);
1088 ATF_TEST_CASE_BODY(set_global__ok)
1089 {
1090 lutok::state state;
1091 lua_pushinteger(raw(state), 3);
1092 state.set_global("test_variable");
1093 ATF_REQUIRE(luaL_dostring(raw(state), "return test_variable + 1") == 0);
1094 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1095 ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -1));
1096 lua_pop(raw(state), 1);
1097 }
1098
1099
1100 ATF_TEST_CASE_WITHOUT_HEAD(set_global__fail);
1101 ATF_TEST_CASE_BODY(set_global__fail)
1102 {
1103 lutok::state state;
1104 lua_pushinteger(raw(state), 3);
1105 lua_replace(raw(state), LUA_GLOBALSINDEX);
1106 lua_pushinteger(raw(state), 4);
1107 REQUIRE_API_ERROR("lua_setglobal", state.set_global("test_variable"));
1108 lua_pop(raw(state), 1);
1109 }
1110
1111
1112 ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__top);
1113 ATF_TEST_CASE_BODY(set_metatable__top)
1114 {
1115 lutok::state state;
1116 ATF_REQUIRE(luaL_dostring(
1117 raw(state),
1118 "mt = {}\n"
1119 "mt.__add = function(a, b) return a[1] + b end\n"
1120 "numbers = {}\n"
1121 "numbers[1] = 5\n") == 0);
1122
1123 lua_getglobal(raw(state), "numbers");
1124 lua_getglobal(raw(state), "mt");
1125 state.set_metatable();
1126 lua_pop(raw(state), 1);
1127
1128 ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
1129 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1130 ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
1131 lua_pop(raw(state), 1);
1132 }
1133
1134
1135 ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__explicit);
1136 ATF_TEST_CASE_BODY(set_metatable__explicit)
1137 {
1138 lutok::state state;
1139 ATF_REQUIRE(luaL_dostring(
1140 raw(state),
1141 "mt = {}\n"
1142 "mt.__add = function(a, b) return a[1] + b end\n"
1143 "numbers = {}\n"
1144 "numbers[1] = 5\n") == 0);
1145
1146 lua_getglobal(raw(state), "numbers");
1147 lua_pushinteger(raw(state), 1234);
1148 lua_getglobal(raw(state), "mt");
1149 state.set_metatable(-3);
1150 lua_pop(raw(state), 2);
1151
1152 ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
1153 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1154 ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
1155 lua_pop(raw(state), 1);
1156 }
1157
1158
1159 ATF_TEST_CASE_WITHOUT_HEAD(set_table__ok);
1160 ATF_TEST_CASE_BODY(set_table__ok)
1161 {
1162 lutok::state state;
1163 ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
1164 lua_getglobal(raw(state), "t");
1165
1166 lua_pushstring(raw(state), "bar");
1167 lua_pushstring(raw(state), "baz");
1168 state.set_table();
1169 ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
1170
1171 lua_pushstring(raw(state), "a");
1172 lua_gettable(raw(state), -2);
1173 ATF_REQUIRE(lua_isnumber(raw(state), -1));
1174 ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -1));
1175 lua_pop(raw(state), 1);
1176
1177 lua_pushstring(raw(state), "bar");
1178 lua_gettable(raw(state), -2);
1179 ATF_REQUIRE(lua_isstring(raw(state), -1));
1180 ATF_REQUIRE_EQ(std::string("baz"), lua_tostring(raw(state), -1));
1181 lua_pop(raw(state), 1);
1182
1183 lua_pop(raw(state), 1);
1184 }
1185
1186
1187 ATF_TEST_CASE_WITHOUT_HEAD(set_table__nil);
1188 ATF_TEST_CASE_BODY(set_table__nil)
1189 {
1190 lutok::state state;
1191 lua_pushnil(raw(state));
1192 lua_pushinteger(raw(state), 1);
1193 lua_pushinteger(raw(state), 2);
1194 REQUIRE_API_ERROR("lua_settable", state.set_table(-3));
1195 lua_pop(raw(state), 3);
1196 }
1197
1198
1199 ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__top);
1200 ATF_TEST_CASE_BODY(to_boolean__top)
1201 {
1202 lutok::state state;
1203 lua_pushboolean(raw(state), 1);
1204 ATF_REQUIRE(state.to_boolean());
1205 lua_pushboolean(raw(state), 0);
1206 ATF_REQUIRE(!state.to_boolean());
1207 lua_pop(raw(state), 2);
1208 }
1209
1210
1211 ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__explicit);
1212 ATF_TEST_CASE_BODY(to_boolean__explicit)
1213 {
1214 lutok::state state;
1215 lua_pushboolean(raw(state), 0);
1216 lua_pushboolean(raw(state), 1);
1217 ATF_REQUIRE(!state.to_boolean(-2));
1218 ATF_REQUIRE(state.to_boolean(-1));
1219 lua_pop(raw(state), 2);
1220 }
1221
1222
1223 ATF_TEST_CASE_WITHOUT_HEAD(to_integer__top);
1224 ATF_TEST_CASE_BODY(to_integer__top)
1225 {
1226 lutok::state state;
1227 lua_pushstring(raw(state), "34");
1228 ATF_REQUIRE_EQ(34, state.to_integer());
1229 lua_pushinteger(raw(state), 12);
1230 ATF_REQUIRE_EQ(12, state.to_integer());
1231 lua_pop(raw(state), 2);
1232 }
1233
1234
1235 ATF_TEST_CASE_WITHOUT_HEAD(to_integer__explicit);
1236 ATF_TEST_CASE_BODY(to_integer__explicit)
1237 {
1238 lutok::state state;
1239 lua_pushinteger(raw(state), 12);
1240 lua_pushstring(raw(state), "foobar");
1241 ATF_REQUIRE_EQ(12, state.to_integer(-2));
1242 lua_pop(raw(state), 2);
1243 }
1244
1245
1246 ATF_TEST_CASE_WITHOUT_HEAD(to_string__top);
1247 ATF_TEST_CASE_BODY(to_string__top)
1248 {
1249 lutok::state state;
1250 lua_pushstring(raw(state), "foobar");
1251 ATF_REQUIRE_EQ("foobar", state.to_string());
1252 lua_pushinteger(raw(state), 12);
1253 ATF_REQUIRE_EQ("12", state.to_string());
1254 lua_pop(raw(state), 2);
1255 }
1256
1257
1258 ATF_TEST_CASE_WITHOUT_HEAD(to_string__explicit);
1259 ATF_TEST_CASE_BODY(to_string__explicit)
1260 {
1261 lutok::state state;
1262 lua_pushstring(raw(state), "foobar");
1263 lua_pushinteger(raw(state), 12);
1264 ATF_REQUIRE_EQ("foobar", state.to_string(-2));
1265 ATF_REQUIRE_EQ("12", state.to_string(-1));
1266 lua_pop(raw(state), 2);
1267 }
1268
1269
1270 ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__top);
1271 ATF_TEST_CASE_BODY(to_userdata__top)
1272 {
1273 lutok::state state;
1274 {
1275 int* pointer = static_cast< int* >(
1276 lua_newuserdata(raw(state), sizeof(int)));
1277 *pointer = 987;
1278 }
1279
1280 int* pointer = state.to_userdata< int >();
1281 ATF_REQUIRE_EQ(987, *pointer);
1282 lua_pop(raw(state), 1);
1283 }
1284
1285
1286 ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__explicit);
1287 ATF_TEST_CASE_BODY(to_userdata__explicit)
1288 {
1289 lutok::state state;
1290 {
1291 int* pointer = static_cast< int* >(
1292 lua_newuserdata(raw(state), sizeof(int)));
1293 *pointer = 987;
1294 }
1295
1296 lua_pushinteger(raw(state), 3);
1297 int* pointer = state.to_userdata< int >(-2);
1298 ATF_REQUIRE_EQ(987, *pointer);
1299 lua_pop(raw(state), 2);
1300 }
1301
1302
1303 ATF_TEST_CASE_WITHOUT_HEAD(upvalue_index);
1304 ATF_TEST_CASE_BODY(upvalue_index)
1305 {
1306 lutok::state state;
1307 lua_pushinteger(raw(state), 25);
1308 lua_pushinteger(raw(state), 30);
1309 lua_pushcclosure(raw(state), c_get_upvalues, 2);
1310 lua_setglobal(raw(state), "c_get_upvalues");
1311
1312 ATF_REQUIRE(luaL_dostring(raw(state),
1313 "return c_get_upvalues()") == 0);
1314 ATF_REQUIRE_EQ(25, lua_tointeger(raw(state), -2));
1315 ATF_REQUIRE_EQ(30, lua_tointeger(raw(state), -1));
1316 lua_pop(raw(state), 2);
1317 }
1318
1319
1320 ATF_INIT_TEST_CASES(tcs)
1321 {
1322 ATF_ADD_TEST_CASE(tcs, close);
1323 ATF_ADD_TEST_CASE(tcs, get_global__ok);
1324 ATF_ADD_TEST_CASE(tcs, get_global__fail);
1325 ATF_ADD_TEST_CASE(tcs, get_global__undefined);
1326 ATF_ADD_TEST_CASE(tcs, get_metafield__ok);
1327 ATF_ADD_TEST_CASE(tcs, get_metafield__undefined);
1328 ATF_ADD_TEST_CASE(tcs, get_metatable__top);
1329 ATF_ADD_TEST_CASE(tcs, get_metatable__explicit);
1330 ATF_ADD_TEST_CASE(tcs, get_metatable__undefined);
1331 ATF_ADD_TEST_CASE(tcs, get_table__ok);
1332 ATF_ADD_TEST_CASE(tcs, get_table__nil);
1333 ATF_ADD_TEST_CASE(tcs, get_table__unknown_index);
1334 ATF_ADD_TEST_CASE(tcs, get_top);
1335 ATF_ADD_TEST_CASE(tcs, globals_index);
1336 ATF_ADD_TEST_CASE(tcs, insert);
1337 ATF_ADD_TEST_CASE(tcs, is_boolean__empty);
1338 ATF_ADD_TEST_CASE(tcs, is_boolean__top);
1339 ATF_ADD_TEST_CASE(tcs, is_boolean__explicit);
1340 ATF_ADD_TEST_CASE(tcs, is_function__empty);
1341 ATF_ADD_TEST_CASE(tcs, is_function__top);
1342 ATF_ADD_TEST_CASE(tcs, is_function__explicit);
1343 ATF_ADD_TEST_CASE(tcs, is_nil__empty);
1344 ATF_ADD_TEST_CASE(tcs, is_nil__top);
1345 ATF_ADD_TEST_CASE(tcs, is_nil__explicit);
1346 ATF_ADD_TEST_CASE(tcs, is_number__empty);
1347 ATF_ADD_TEST_CASE(tcs, is_number__top);
1348 ATF_ADD_TEST_CASE(tcs, is_number__explicit);
1349 ATF_ADD_TEST_CASE(tcs, is_string__empty);
1350 ATF_ADD_TEST_CASE(tcs, is_string__top);
1351 ATF_ADD_TEST_CASE(tcs, is_string__explicit);
1352 ATF_ADD_TEST_CASE(tcs, is_table__empty);
1353 ATF_ADD_TEST_CASE(tcs, is_table__top);
1354 ATF_ADD_TEST_CASE(tcs, is_table__explicit);
1355 ATF_ADD_TEST_CASE(tcs, is_userdata__empty);
1356 ATF_ADD_TEST_CASE(tcs, is_userdata__top);
1357 ATF_ADD_TEST_CASE(tcs, is_userdata__explicit);
1358 ATF_ADD_TEST_CASE(tcs, load_file__ok);
1359 ATF_ADD_TEST_CASE(tcs, load_file__api_error);
1360 ATF_ADD_TEST_CASE(tcs, load_file__file_not_found_error);
1361 ATF_ADD_TEST_CASE(tcs, load_string__ok);
1362 ATF_ADD_TEST_CASE(tcs, load_string__fail);
1363 ATF_ADD_TEST_CASE(tcs, new_table);
1364 ATF_ADD_TEST_CASE(tcs, new_userdata);
1365 ATF_ADD_TEST_CASE(tcs, next__empty);
1366 ATF_ADD_TEST_CASE(tcs, next__many);
1367 ATF_ADD_TEST_CASE(tcs, open_base);
1368 ATF_ADD_TEST_CASE(tcs, open_string);
1369 ATF_ADD_TEST_CASE(tcs, open_table);
1370 ATF_ADD_TEST_CASE(tcs, pcall__ok);
1371 ATF_ADD_TEST_CASE(tcs, pcall__fail);
1372 ATF_ADD_TEST_CASE(tcs, pop__one);
1373 ATF_ADD_TEST_CASE(tcs, pop__many);
1374 ATF_ADD_TEST_CASE(tcs, push_boolean);
1375 ATF_ADD_TEST_CASE(tcs, push_cxx_closure);
1376 ATF_ADD_TEST_CASE(tcs, push_cxx_function__ok);
1377 ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_exception);
1378 ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_anything);
1379 ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_overflow);
1380 ATF_ADD_TEST_CASE(tcs, push_integer);
1381 ATF_ADD_TEST_CASE(tcs, push_nil);
1382 ATF_ADD_TEST_CASE(tcs, push_string);
1383 ATF_ADD_TEST_CASE(tcs, push_value__top);
1384 ATF_ADD_TEST_CASE(tcs, push_value__explicit);
1385 ATF_ADD_TEST_CASE(tcs, raw_get__top);
1386 ATF_ADD_TEST_CASE(tcs, raw_get__explicit);
1387 ATF_ADD_TEST_CASE(tcs, raw_set__top);
1388 ATF_ADD_TEST_CASE(tcs, raw_set__explicit);
1389 ATF_ADD_TEST_CASE(tcs, set_global__ok);
1390 ATF_ADD_TEST_CASE(tcs, set_global__fail);
1391 ATF_ADD_TEST_CASE(tcs, set_metatable__top);
1392 ATF_ADD_TEST_CASE(tcs, set_metatable__explicit);
1393 ATF_ADD_TEST_CASE(tcs, set_table__ok);
1394 ATF_ADD_TEST_CASE(tcs, set_table__nil);
1395 ATF_ADD_TEST_CASE(tcs, to_boolean__top);
1396 ATF_ADD_TEST_CASE(tcs, to_boolean__explicit);
1397 ATF_ADD_TEST_CASE(tcs, to_integer__top);
1398 ATF_ADD_TEST_CASE(tcs, to_integer__explicit);
1399 ATF_ADD_TEST_CASE(tcs, to_string__top);
1400 ATF_ADD_TEST_CASE(tcs, to_string__explicit);
1401 ATF_ADD_TEST_CASE(tcs, to_userdata__top);
1402 ATF_ADD_TEST_CASE(tcs, to_userdata__explicit);
1403 ATF_ADD_TEST_CASE(tcs, upvalue_index);
1404 }
1405