xref: /netbsd-src/external/bsd/lutok/dist/state_test.cpp (revision a4ddc2c8fb9af816efe3b1c375a5530aef0e89e9)
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