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
59namespace {
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.
68static bool
69is_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.
87static void
88check_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.
108static int
109c_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.
128static int
129cxx_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.
153static int
154cxx_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.
178static int
179raise_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
189ATF_TEST_CASE_WITHOUT_HEAD(close);
190ATF_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
199ATF_TEST_CASE_WITHOUT_HEAD(get_global__ok);
200ATF_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
210ATF_TEST_CASE_WITHOUT_HEAD(get_global__undefined);
211ATF_TEST_CASE_BODY(get_global__undefined)
212{
213    lutok::state state;
214    state.get_global("test_variable");
215    ATF_REQUIRE(lua_isnil(raw(state), -1));
216    lua_pop(raw(state), 1);
217}
218
219
220ATF_TEST_CASE_WITHOUT_HEAD(get_global_table);
221ATF_TEST_CASE_BODY(get_global_table)
222{
223    lutok::state state;
224    ATF_REQUIRE(luaL_dostring(raw(state), "global_variable = 'hello'") == 0);
225    state.get_global_table();
226    lua_pushstring(raw(state), "global_variable");
227    lua_gettable(raw(state), -2);
228    ATF_REQUIRE(lua_isstring(raw(state), -1));
229    ATF_REQUIRE(std::strcmp("hello", lua_tostring(raw(state), -1)) == 0);
230    lua_pop(raw(state), 2);
231}
232
233
234ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__ok);
235ATF_TEST_CASE_BODY(get_metafield__ok)
236{
237    lutok::state state;
238    luaL_openlibs(raw(state));
239    ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
240                              "t = {}; setmetatable(t, meta)") == 0);
241    lua_getglobal(raw(state), "t");
242    ATF_REQUIRE(state.get_metafield(-1, "foo"));
243    ATF_REQUIRE(lua_isnumber(raw(state), -1));
244    ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
245    lua_pop(raw(state), 2);
246}
247
248
249ATF_TEST_CASE_WITHOUT_HEAD(get_metafield__undefined);
250ATF_TEST_CASE_BODY(get_metafield__undefined)
251{
252    lutok::state state;
253    luaL_openlibs(raw(state));
254    ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
255                              "t = {}; setmetatable(t, meta)") == 0);
256    lua_getglobal(raw(state), "t");
257    ATF_REQUIRE(!state.get_metafield(-1, "bar"));
258    lua_pop(raw(state), 1);
259}
260
261
262ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__top);
263ATF_TEST_CASE_BODY(get_metatable__top)
264{
265    lutok::state state;
266    luaL_openlibs(raw(state));
267    ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
268                              "t = {}; setmetatable(t, meta)") == 0);
269    lua_getglobal(raw(state), "t");
270    ATF_REQUIRE(state.get_metatable());
271    ATF_REQUIRE(lua_istable(raw(state), -1));
272    lua_pushstring(raw(state), "foo");
273    lua_gettable(raw(state), -2);
274    ATF_REQUIRE(lua_isnumber(raw(state), -1));
275    ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
276    lua_pop(raw(state), 3);
277}
278
279
280ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__explicit);
281ATF_TEST_CASE_BODY(get_metatable__explicit)
282{
283    lutok::state state;
284    luaL_openlibs(raw(state));
285    ATF_REQUIRE(luaL_dostring(raw(state), "meta = { foo = 567 }; "
286                              "t = {}; setmetatable(t, meta)") == 0);
287    lua_getglobal(raw(state), "t");
288    lua_pushinteger(raw(state), 5555);
289    ATF_REQUIRE(state.get_metatable(-2));
290    ATF_REQUIRE(lua_istable(raw(state), -1));
291    lua_pushstring(raw(state), "foo");
292    lua_gettable(raw(state), -2);
293    ATF_REQUIRE(lua_isnumber(raw(state), -1));
294    ATF_REQUIRE_EQ(567, lua_tointeger(raw(state), -1));
295    lua_pop(raw(state), 4);
296}
297
298
299ATF_TEST_CASE_WITHOUT_HEAD(get_metatable__undefined);
300ATF_TEST_CASE_BODY(get_metatable__undefined)
301{
302    lutok::state state;
303    ATF_REQUIRE(luaL_dostring(raw(state), "t = {}") == 0);
304    lua_getglobal(raw(state), "t");
305    ATF_REQUIRE(!state.get_metatable(-1));
306    lua_pop(raw(state), 1);
307}
308
309
310ATF_TEST_CASE_WITHOUT_HEAD(get_table__ok);
311ATF_TEST_CASE_BODY(get_table__ok)
312{
313    lutok::state state;
314    ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
315    lua_getglobal(raw(state), "t");
316    lua_pushstring(raw(state), "bar");
317    state.get_table();
318    ATF_REQUIRE(lua_isnumber(raw(state), -1));
319    ATF_REQUIRE_EQ(234, lua_tointeger(raw(state), -1));
320    lua_pop(raw(state), 2);
321}
322
323
324ATF_TEST_CASE_WITHOUT_HEAD(get_table__nil);
325ATF_TEST_CASE_BODY(get_table__nil)
326{
327    lutok::state state;
328    lua_pushnil(raw(state));
329    lua_pushinteger(raw(state), 1);
330    REQUIRE_API_ERROR("lua_gettable", state.get_table());
331    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
332    lua_pop(raw(state), 2);
333}
334
335
336ATF_TEST_CASE_WITHOUT_HEAD(get_table__unknown_index);
337ATF_TEST_CASE_BODY(get_table__unknown_index)
338{
339    lutok::state state;
340    ATF_REQUIRE(luaL_dostring(raw(state),
341                              "the_table = { foo = 1, bar = 2 }") == 0);
342    lua_getglobal(raw(state), "the_table");
343    lua_pushstring(raw(state), "baz");
344    state.get_table();
345    ATF_REQUIRE(lua_isnil(raw(state), -1));
346    lua_pop(raw(state), 2);
347}
348
349
350ATF_TEST_CASE_WITHOUT_HEAD(get_top);
351ATF_TEST_CASE_BODY(get_top)
352{
353    lutok::state state;
354    ATF_REQUIRE_EQ(0, state.get_top());
355    lua_pushinteger(raw(state), 3);
356    ATF_REQUIRE_EQ(1, state.get_top());
357    lua_pushinteger(raw(state), 3);
358    ATF_REQUIRE_EQ(2, state.get_top());
359    lua_pop(raw(state), 2);
360}
361
362
363ATF_TEST_CASE_WITHOUT_HEAD(insert);
364ATF_TEST_CASE_BODY(insert)
365{
366    lutok::state state;
367    lua_pushinteger(raw(state), 1);
368    lua_pushinteger(raw(state), 2);
369    lua_pushinteger(raw(state), 3);
370    lua_pushinteger(raw(state), 4);
371    state.insert(-3);
372    ATF_REQUIRE_EQ(3, lua_tointeger(raw(state), -1));
373    ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
374    ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -3));
375    ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -4));
376    lua_pop(raw(state), 4);
377}
378
379
380ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__empty);
381ATF_TEST_CASE_BODY(is_boolean__empty)
382{
383    lutok::state state;
384    ATF_REQUIRE(!state.is_boolean());
385}
386
387
388ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__top);
389ATF_TEST_CASE_BODY(is_boolean__top)
390{
391    lutok::state state;
392    lua_pushnil(raw(state));
393    ATF_REQUIRE(!state.is_boolean());
394    lua_pushboolean(raw(state), 1);
395    ATF_REQUIRE(state.is_boolean());
396    lua_pop(raw(state), 2);
397}
398
399
400ATF_TEST_CASE_WITHOUT_HEAD(is_boolean__explicit);
401ATF_TEST_CASE_BODY(is_boolean__explicit)
402{
403    lutok::state state;
404    lua_pushboolean(raw(state), 1);
405    ATF_REQUIRE(state.is_boolean(-1));
406    lua_pushinteger(raw(state), 5);
407    ATF_REQUIRE(!state.is_boolean(-1));
408    ATF_REQUIRE(state.is_boolean(-2));
409    lua_pop(raw(state), 2);
410}
411
412
413ATF_TEST_CASE_WITHOUT_HEAD(is_function__empty);
414ATF_TEST_CASE_BODY(is_function__empty)
415{
416    lutok::state state;
417    ATF_REQUIRE(!state.is_function());
418}
419
420
421ATF_TEST_CASE_WITHOUT_HEAD(is_function__top);
422ATF_TEST_CASE_BODY(is_function__top)
423{
424    lutok::state state;
425    luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
426
427    lua_pushnil(raw(state));
428    ATF_REQUIRE(!state.is_function());
429    lua_getglobal(raw(state), "my_func");
430    ATF_REQUIRE(state.is_function());
431    lua_pop(raw(state), 2);
432}
433
434
435ATF_TEST_CASE_WITHOUT_HEAD(is_function__explicit);
436ATF_TEST_CASE_BODY(is_function__explicit)
437{
438    lutok::state state;
439    luaL_dostring(raw(state), "function my_func(a, b) return a + b; end");
440
441    lua_getglobal(raw(state), "my_func");
442    ATF_REQUIRE(state.is_function(-1));
443    lua_pushinteger(raw(state), 5);
444    ATF_REQUIRE(!state.is_function(-1));
445    ATF_REQUIRE(state.is_function(-2));
446    lua_pop(raw(state), 2);
447}
448
449
450ATF_TEST_CASE_WITHOUT_HEAD(is_nil__empty);
451ATF_TEST_CASE_BODY(is_nil__empty)
452{
453    lutok::state state;
454    ATF_REQUIRE(state.is_nil());
455}
456
457
458ATF_TEST_CASE_WITHOUT_HEAD(is_nil__top);
459ATF_TEST_CASE_BODY(is_nil__top)
460{
461    lutok::state state;
462    lua_pushnil(raw(state));
463    ATF_REQUIRE(state.is_nil());
464    lua_pushinteger(raw(state), 5);
465    ATF_REQUIRE(!state.is_nil());
466    lua_pop(raw(state), 2);
467}
468
469
470ATF_TEST_CASE_WITHOUT_HEAD(is_nil__explicit);
471ATF_TEST_CASE_BODY(is_nil__explicit)
472{
473    lutok::state state;
474    lua_pushnil(raw(state));
475    ATF_REQUIRE(state.is_nil(-1));
476    lua_pushinteger(raw(state), 5);
477    ATF_REQUIRE(!state.is_nil(-1));
478    ATF_REQUIRE(state.is_nil(-2));
479    lua_pop(raw(state), 2);
480}
481
482
483ATF_TEST_CASE_WITHOUT_HEAD(is_number__empty);
484ATF_TEST_CASE_BODY(is_number__empty)
485{
486    lutok::state state;
487    ATF_REQUIRE(!state.is_number());
488}
489
490
491ATF_TEST_CASE_WITHOUT_HEAD(is_number__top);
492ATF_TEST_CASE_BODY(is_number__top)
493{
494    lutok::state state;
495    lua_pushnil(raw(state));
496    ATF_REQUIRE(!state.is_number());
497    lua_pushinteger(raw(state), 5);
498    ATF_REQUIRE(state.is_number());
499    lua_pop(raw(state), 2);
500}
501
502
503ATF_TEST_CASE_WITHOUT_HEAD(is_number__explicit);
504ATF_TEST_CASE_BODY(is_number__explicit)
505{
506    lutok::state state;
507    lua_pushnil(raw(state));
508    ATF_REQUIRE(!state.is_number(-1));
509    lua_pushinteger(raw(state), 5);
510    ATF_REQUIRE(state.is_number(-1));
511    ATF_REQUIRE(!state.is_number(-2));
512    lua_pop(raw(state), 2);
513}
514
515
516ATF_TEST_CASE_WITHOUT_HEAD(is_string__empty);
517ATF_TEST_CASE_BODY(is_string__empty)
518{
519    lutok::state state;
520    ATF_REQUIRE(!state.is_string());
521}
522
523
524ATF_TEST_CASE_WITHOUT_HEAD(is_string__top);
525ATF_TEST_CASE_BODY(is_string__top)
526{
527    lutok::state state;
528    lua_pushnil(raw(state));
529    ATF_REQUIRE(!state.is_string());
530    lua_pushinteger(raw(state), 3);
531    ATF_REQUIRE(state.is_string());
532    lua_pushstring(raw(state), "foo");
533    ATF_REQUIRE(state.is_string());
534    lua_pop(raw(state), 3);
535}
536
537
538ATF_TEST_CASE_WITHOUT_HEAD(is_string__explicit);
539ATF_TEST_CASE_BODY(is_string__explicit)
540{
541    lutok::state state;
542    lua_pushinteger(raw(state), 3);
543    ATF_REQUIRE(state.is_string(-1));
544    lua_pushnil(raw(state));
545    ATF_REQUIRE(!state.is_string(-1));
546    ATF_REQUIRE(state.is_string(-2));
547    lua_pushstring(raw(state), "foo");
548    ATF_REQUIRE(state.is_string(-1));
549    ATF_REQUIRE(!state.is_string(-2));
550    ATF_REQUIRE(state.is_string(-3));
551    lua_pop(raw(state), 3);
552}
553
554
555ATF_TEST_CASE_WITHOUT_HEAD(is_table__empty);
556ATF_TEST_CASE_BODY(is_table__empty)
557{
558    lutok::state state;
559    ATF_REQUIRE(!state.is_table());
560}
561
562
563ATF_TEST_CASE_WITHOUT_HEAD(is_table__top);
564ATF_TEST_CASE_BODY(is_table__top)
565{
566    lutok::state state;
567    luaL_dostring(raw(state), "t = {3, 4, 5}");
568
569    lua_pushstring(raw(state), "foo");
570    ATF_REQUIRE(!state.is_table());
571    lua_getglobal(raw(state), "t");
572    ATF_REQUIRE(state.is_table());
573    lua_pop(raw(state), 2);
574}
575
576
577ATF_TEST_CASE_WITHOUT_HEAD(is_table__explicit);
578ATF_TEST_CASE_BODY(is_table__explicit)
579{
580    lutok::state state;
581    luaL_dostring(raw(state), "t = {3, 4, 5}");
582
583    lua_pushstring(raw(state), "foo");
584    ATF_REQUIRE(!state.is_table(-1));
585    lua_getglobal(raw(state), "t");
586    ATF_REQUIRE(state.is_table(-1));
587    ATF_REQUIRE(!state.is_table(-2));
588    lua_pop(raw(state), 2);
589}
590
591
592ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__empty);
593ATF_TEST_CASE_BODY(is_userdata__empty)
594{
595    lutok::state state;
596    ATF_REQUIRE(!state.is_userdata());
597}
598
599
600ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__top);
601ATF_TEST_CASE_BODY(is_userdata__top)
602{
603    lutok::state state;
604
605    lua_pushstring(raw(state), "foo");
606    ATF_REQUIRE(!state.is_userdata());
607    lua_newuserdata(raw(state), 1234);
608    ATF_REQUIRE(state.is_userdata());
609    lua_pop(raw(state), 2);
610}
611
612
613ATF_TEST_CASE_WITHOUT_HEAD(is_userdata__explicit);
614ATF_TEST_CASE_BODY(is_userdata__explicit)
615{
616    lutok::state state;
617
618    lua_pushstring(raw(state), "foo");
619    ATF_REQUIRE(!state.is_userdata(-1));
620    lua_newuserdata(raw(state), 543);
621    ATF_REQUIRE(state.is_userdata(-1));
622    ATF_REQUIRE(!state.is_userdata(-2));
623    lua_pop(raw(state), 2);
624}
625
626
627ATF_TEST_CASE_WITHOUT_HEAD(load_file__ok);
628ATF_TEST_CASE_BODY(load_file__ok)
629{
630    std::ofstream output("test.lua");
631    output << "in_the_file = \"oh yes\"\n";
632    output.close();
633
634    lutok::state state;
635    state.load_file("test.lua");
636    ATF_REQUIRE(lua_pcall(raw(state), 0, 0, 0) == 0);
637    lua_getglobal(raw(state), "in_the_file");
638    ATF_REQUIRE(std::strcmp("oh yes", lua_tostring(raw(state), -1)) == 0);
639    lua_pop(raw(state), 1);
640}
641
642
643ATF_TEST_CASE_WITHOUT_HEAD(load_file__api_error);
644ATF_TEST_CASE_BODY(load_file__api_error)
645{
646    std::ofstream output("test.lua");
647    output << "I have a bad syntax!  Wohoo!\n";
648    output.close();
649
650    lutok::state state;
651    REQUIRE_API_ERROR("luaL_loadfile", state.load_file("test.lua"));
652}
653
654
655ATF_TEST_CASE_WITHOUT_HEAD(load_file__file_not_found_error);
656ATF_TEST_CASE_BODY(load_file__file_not_found_error)
657{
658    lutok::state state;
659    ATF_REQUIRE_THROW_RE(lutok::file_not_found_error, "missing.lua",
660                         state.load_file("missing.lua"));
661}
662
663
664ATF_TEST_CASE_WITHOUT_HEAD(load_string__ok);
665ATF_TEST_CASE_BODY(load_string__ok)
666{
667    lutok::state state;
668    state.load_string("return 2 + 3");
669    ATF_REQUIRE(lua_pcall(raw(state), 0, 1, 0) == 0);
670    ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -1));
671    lua_pop(raw(state), 1);
672}
673
674
675ATF_TEST_CASE_WITHOUT_HEAD(load_string__fail);
676ATF_TEST_CASE_BODY(load_string__fail)
677{
678    lutok::state state;
679    REQUIRE_API_ERROR("luaL_loadstring", state.load_string("-"));
680}
681
682
683ATF_TEST_CASE_WITHOUT_HEAD(new_table);
684ATF_TEST_CASE_BODY(new_table)
685{
686    lutok::state state;
687    state.new_table();
688    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
689    ATF_REQUIRE(lua_istable(raw(state), -1));
690    lua_pop(raw(state), 1);
691}
692
693
694ATF_TEST_CASE_WITHOUT_HEAD(new_userdata);
695ATF_TEST_CASE_BODY(new_userdata)
696{
697    lutok::state state;
698    int* pointer = state.new_userdata< int >();
699    *pointer = 1234;
700    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
701    ATF_REQUIRE(lua_isuserdata(raw(state), -1));
702    lua_pop(raw(state), 1);
703}
704
705
706ATF_TEST_CASE_WITHOUT_HEAD(next__empty);
707ATF_TEST_CASE_BODY(next__empty)
708{
709    lutok::state state;
710    luaL_dostring(raw(state), "t = {}");
711
712    lua_getglobal(raw(state), "t");
713    lua_pushstring(raw(state), "this is a dummy value");
714    lua_pushnil(raw(state));
715    ATF_REQUIRE(!state.next(-3));
716    lua_pop(raw(state), 2);
717}
718
719
720ATF_TEST_CASE_WITHOUT_HEAD(next__many);
721ATF_TEST_CASE_BODY(next__many)
722{
723    lutok::state state;
724    luaL_dostring(raw(state), "t = {}; t[1] = 100; t[2] = 200");
725
726    lua_getglobal(raw(state), "t");
727    lua_pushnil(raw(state));
728
729    ATF_REQUIRE(state.next());
730    ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
731    ATF_REQUIRE(lua_isnumber(raw(state), -2));
732    ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -2));
733    ATF_REQUIRE(lua_isnumber(raw(state), -1));
734    ATF_REQUIRE_EQ(100, lua_tointeger(raw(state), -1));
735    lua_pop(raw(state), 1);
736
737    ATF_REQUIRE(state.next());
738    ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
739    ATF_REQUIRE(lua_isnumber(raw(state), -2));
740    ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -2));
741    ATF_REQUIRE(lua_isnumber(raw(state), -1));
742    ATF_REQUIRE_EQ(200, lua_tointeger(raw(state), -1));
743    lua_pop(raw(state), 1);
744
745    ATF_REQUIRE(!state.next());
746    lua_pop(raw(state), 1);
747}
748
749
750ATF_TEST_CASE_WITHOUT_HEAD(open_base);
751ATF_TEST_CASE_BODY(open_base)
752{
753    lutok::state state;
754    check_modules(state, "");
755    state.open_base();
756    check_modules(state, "base");
757}
758
759
760ATF_TEST_CASE_WITHOUT_HEAD(open_string);
761ATF_TEST_CASE_BODY(open_string)
762{
763    lutok::state state;
764    check_modules(state, "");
765    state.open_string();
766    check_modules(state, "string");
767}
768
769
770ATF_TEST_CASE_WITHOUT_HEAD(open_table);
771ATF_TEST_CASE_BODY(open_table)
772{
773    lutok::state state;
774    check_modules(state, "");
775    state.open_table();
776    check_modules(state, "table");
777}
778
779
780ATF_TEST_CASE_WITHOUT_HEAD(pcall__ok);
781ATF_TEST_CASE_BODY(pcall__ok)
782{
783    lutok::state state;
784    luaL_loadstring(raw(state), "function mul(a, b) return a * b; end");
785    state.pcall(0, 0, 0);
786    state.get_global_table();
787    lua_pushstring(raw(state), "mul");
788    lua_gettable(raw(state), -2);
789    lua_pushinteger(raw(state), 3);
790    lua_pushinteger(raw(state), 5);
791    state.pcall(2, 1, 0);
792    ATF_REQUIRE_EQ(15, lua_tointeger(raw(state), -1));
793    lua_pop(raw(state), 2);
794}
795
796
797ATF_TEST_CASE_WITHOUT_HEAD(pcall__fail);
798ATF_TEST_CASE_BODY(pcall__fail)
799{
800    lutok::state state;
801    lua_pushnil(raw(state));
802    REQUIRE_API_ERROR("lua_pcall", state.pcall(0, 0, 0));
803}
804
805
806ATF_TEST_CASE_WITHOUT_HEAD(pop__one);
807ATF_TEST_CASE_BODY(pop__one)
808{
809    lutok::state state;
810    lua_pushinteger(raw(state), 10);
811    lua_pushinteger(raw(state), 20);
812    lua_pushinteger(raw(state), 30);
813    state.pop(1);
814    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
815    ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
816    lua_pop(raw(state), 2);
817}
818
819
820ATF_TEST_CASE_WITHOUT_HEAD(pop__many);
821ATF_TEST_CASE_BODY(pop__many)
822{
823    lutok::state state;
824    lua_pushinteger(raw(state), 10);
825    lua_pushinteger(raw(state), 20);
826    lua_pushinteger(raw(state), 30);
827    state.pop(2);
828    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
829    ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
830    lua_pop(raw(state), 1);
831}
832
833
834ATF_TEST_CASE_WITHOUT_HEAD(push_boolean);
835ATF_TEST_CASE_BODY(push_boolean)
836{
837    lutok::state state;
838    state.push_boolean(true);
839    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
840    ATF_REQUIRE(lua_toboolean(raw(state), -1));
841    state.push_boolean(false);
842    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
843    ATF_REQUIRE(!lua_toboolean(raw(state), -1));
844    ATF_REQUIRE(lua_toboolean(raw(state), -2));
845    lua_pop(raw(state), 2);
846}
847
848
849ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_closure);
850ATF_TEST_CASE_BODY(push_cxx_closure)
851{
852    lutok::state state;
853    state.push_integer(15);
854    state.push_cxx_closure(cxx_multiply_closure, 1);
855    lua_setglobal(raw(state), "cxx_multiply_closure");
856
857    ATF_REQUIRE(luaL_dostring(raw(state),
858                              "return cxx_multiply_closure(10)") == 0);
859    ATF_REQUIRE_EQ(150, lua_tointeger(raw(state), -1));
860    lua_pop(raw(state), 1);
861}
862
863
864ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__ok);
865ATF_TEST_CASE_BODY(push_cxx_function__ok)
866{
867    lutok::state state;
868    state.push_cxx_function(cxx_divide);
869    lua_setglobal(raw(state), "cxx_divide");
870
871    ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(17, 3)") == 0);
872    ATF_REQUIRE_EQ(5, lua_tointeger(raw(state), -2));
873    ATF_REQUIRE_EQ(2, lua_tointeger(raw(state), -1));
874    lua_pop(raw(state), 2);
875}
876
877
878ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_exception);
879ATF_TEST_CASE_BODY(push_cxx_function__fail_exception)
880{
881    lutok::state state;
882    state.push_cxx_function(cxx_divide);
883    lua_setglobal(raw(state), "cxx_divide");
884
885    ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(15, 0)") != 0);
886    ATF_REQUIRE_MATCH("Divisor is 0", lua_tostring(raw(state), -1));
887    lua_pop(raw(state), 1);
888}
889
890
891ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_anything);
892ATF_TEST_CASE_BODY(push_cxx_function__fail_anything)
893{
894    lutok::state state;
895    state.push_cxx_function(cxx_divide);
896    lua_setglobal(raw(state), "cxx_divide");
897
898    ATF_REQUIRE(luaL_dostring(raw(state), "return cxx_divide(-3, -1)") != 0);
899    ATF_REQUIRE_MATCH("Unhandled exception", lua_tostring(raw(state), -1));
900    lua_pop(raw(state), 1);
901}
902
903
904ATF_TEST_CASE_WITHOUT_HEAD(push_cxx_function__fail_overflow);
905ATF_TEST_CASE_BODY(push_cxx_function__fail_overflow)
906{
907    lutok::state state;
908    state.push_cxx_function(raise_long_error);
909    lua_setglobal(raw(state), "fail");
910
911    ATF_REQUIRE(luaL_dostring(raw(state), "return fail(900)") != 0);
912    ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
913    lua_pop(raw(state), 1);
914
915    ATF_REQUIRE(luaL_dostring(raw(state), "return fail(8192)") != 0);
916    ATF_REQUIRE_MATCH(std::string(900, 'A'), lua_tostring(raw(state), -1));
917    lua_pop(raw(state), 1);
918}
919
920
921ATF_TEST_CASE_WITHOUT_HEAD(push_integer);
922ATF_TEST_CASE_BODY(push_integer)
923{
924    lutok::state state;
925    state.push_integer(12);
926    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
927    ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -1));
928    state.push_integer(34);
929    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
930    ATF_REQUIRE_EQ(34, lua_tointeger(raw(state), -1));
931    ATF_REQUIRE_EQ(12, lua_tointeger(raw(state), -2));
932    lua_pop(raw(state), 2);
933}
934
935
936ATF_TEST_CASE_WITHOUT_HEAD(push_nil);
937ATF_TEST_CASE_BODY(push_nil)
938{
939    lutok::state state;
940    state.push_nil();
941    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
942    ATF_REQUIRE(lua_isnil(raw(state), -1));
943    state.push_integer(34);
944    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
945    ATF_REQUIRE(!lua_isnil(raw(state), -1));
946    ATF_REQUIRE(lua_isnil(raw(state), -2));
947    lua_pop(raw(state), 2);
948}
949
950
951ATF_TEST_CASE_WITHOUT_HEAD(push_string);
952ATF_TEST_CASE_BODY(push_string)
953{
954    lutok::state state;
955
956    {
957        std::string str = "first";
958        state.push_string(str);
959        ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
960        ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -1));
961        str = "second";
962        state.push_string(str);
963    }
964    ATF_REQUIRE_EQ(2, lua_gettop(raw(state)));
965    ATF_REQUIRE_EQ(std::string("second"), lua_tostring(raw(state), -1));
966    ATF_REQUIRE_EQ(std::string("first"), lua_tostring(raw(state), -2));
967    lua_pop(raw(state), 2);
968}
969
970
971ATF_TEST_CASE_WITHOUT_HEAD(push_value__top);
972ATF_TEST_CASE_BODY(push_value__top)
973{
974    lutok::state state;
975
976    lua_pushinteger(raw(state), 10);
977    lua_pushinteger(raw(state), 20);
978    state.push_value();
979    ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
980    ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -1));
981    ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
982    ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
983    lua_pop(raw(state), 3);
984}
985
986
987ATF_TEST_CASE_WITHOUT_HEAD(push_value__explicit);
988ATF_TEST_CASE_BODY(push_value__explicit)
989{
990    lutok::state state;
991
992    lua_pushinteger(raw(state), 10);
993    lua_pushinteger(raw(state), 20);
994    state.push_value(-2);
995    ATF_REQUIRE_EQ(3, lua_gettop(raw(state)));
996    ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -1));
997    ATF_REQUIRE_EQ(20, lua_tointeger(raw(state), -2));
998    ATF_REQUIRE_EQ(10, lua_tointeger(raw(state), -3));
999    lua_pop(raw(state), 3);
1000}
1001
1002
1003ATF_TEST_CASE_WITHOUT_HEAD(raw_get__top);
1004ATF_TEST_CASE_BODY(raw_get__top)
1005{
1006    lutok::state state;
1007
1008    luaL_openlibs(raw(state));
1009    ATF_REQUIRE(luaL_dostring(
1010        raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
1011    lua_getglobal(raw(state), "t");
1012    lua_pushstring(raw(state), "foo");
1013    state.raw_get();
1014    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1015    ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
1016    lua_pop(raw(state), 2);
1017}
1018
1019
1020ATF_TEST_CASE_WITHOUT_HEAD(raw_get__explicit);
1021ATF_TEST_CASE_BODY(raw_get__explicit)
1022{
1023    lutok::state state;
1024
1025    luaL_openlibs(raw(state));
1026    ATF_REQUIRE(luaL_dostring(
1027        raw(state), "t = {foo=123} ; setmetatable(t, {__index=1})") == 0);
1028    lua_getglobal(raw(state), "t");
1029    lua_pushinteger(raw(state), 9876);
1030    lua_pushstring(raw(state), "foo");
1031    state.raw_get(-3);
1032    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1033    ATF_REQUIRE_EQ(123, lua_tointeger(raw(state), -1));
1034    ATF_REQUIRE_EQ(9876, lua_tointeger(raw(state), -2));
1035    lua_pop(raw(state), 3);
1036}
1037
1038
1039ATF_TEST_CASE_WITHOUT_HEAD(raw_set__top);
1040ATF_TEST_CASE_BODY(raw_set__top)
1041{
1042    lutok::state state;
1043
1044    luaL_openlibs(raw(state));
1045    ATF_REQUIRE(luaL_dostring(
1046        raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
1047    lua_getglobal(raw(state), "t");
1048    lua_pushstring(raw(state), "foo");
1049    lua_pushinteger(raw(state), 345);
1050    state.raw_set();
1051    ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
1052    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1053    ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
1054    lua_pop(raw(state), 2);
1055}
1056
1057
1058ATF_TEST_CASE_WITHOUT_HEAD(raw_set__explicit);
1059ATF_TEST_CASE_BODY(raw_set__explicit)
1060{
1061    lutok::state state;
1062
1063    luaL_openlibs(raw(state));
1064    ATF_REQUIRE(luaL_dostring(
1065        raw(state), "t = {} ; setmetatable(t, {__newindex=1})") == 0);
1066    lua_getglobal(raw(state), "t");
1067    lua_pushinteger(raw(state), 876);
1068    lua_pushstring(raw(state), "foo");
1069    lua_pushinteger(raw(state), 345);
1070    state.raw_set(-4);
1071    ATF_REQUIRE(luaL_dostring(raw(state), "return t.foo") == 0);
1072    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1073    ATF_REQUIRE_EQ(345, lua_tointeger(raw(state), -1));
1074    ATF_REQUIRE_EQ(876, lua_tointeger(raw(state), -2));
1075    lua_pop(raw(state), 3);
1076}
1077
1078
1079ATF_TEST_CASE_WITHOUT_HEAD(registry_index);
1080ATF_TEST_CASE_BODY(registry_index)
1081{
1082    lutok::state state;
1083    lua_pushvalue(raw(state), lutok::registry_index);
1084    lua_pushstring(raw(state), "custom_variable");
1085    lua_pushstring(raw(state), "custom value");
1086    lua_settable(raw(state), -3);
1087    lua_pop(raw(state), 1);
1088    ATF_REQUIRE(luaL_dostring(raw(state),
1089                              "return custom_variable == nil") == 0);
1090    ATF_REQUIRE(lua_isboolean(raw(state), -1));
1091    ATF_REQUIRE(lua_toboolean(raw(state), -1));
1092    lua_pop(raw(state), 1);
1093}
1094
1095
1096ATF_TEST_CASE_WITHOUT_HEAD(set_global);
1097ATF_TEST_CASE_BODY(set_global)
1098{
1099    lutok::state state;
1100    lua_pushinteger(raw(state), 3);
1101    state.set_global("test_variable");
1102    ATF_REQUIRE(luaL_dostring(raw(state), "return test_variable + 1") == 0);
1103    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1104    ATF_REQUIRE_EQ(4, lua_tointeger(raw(state), -1));
1105    lua_pop(raw(state), 1);
1106}
1107
1108
1109ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__top);
1110ATF_TEST_CASE_BODY(set_metatable__top)
1111{
1112    lutok::state state;
1113    ATF_REQUIRE(luaL_dostring(
1114        raw(state),
1115        "mt = {}\n"
1116        "mt.__add = function(a, b) return a[1] + b end\n"
1117        "numbers = {}\n"
1118        "numbers[1] = 5\n") == 0);
1119
1120    lua_getglobal(raw(state), "numbers");
1121    lua_getglobal(raw(state), "mt");
1122    state.set_metatable();
1123    lua_pop(raw(state), 1);
1124
1125    ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
1126    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1127    ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
1128    lua_pop(raw(state), 1);
1129}
1130
1131
1132ATF_TEST_CASE_WITHOUT_HEAD(set_metatable__explicit);
1133ATF_TEST_CASE_BODY(set_metatable__explicit)
1134{
1135    lutok::state state;
1136    ATF_REQUIRE(luaL_dostring(
1137        raw(state),
1138        "mt = {}\n"
1139        "mt.__add = function(a, b) return a[1] + b end\n"
1140        "numbers = {}\n"
1141        "numbers[1] = 5\n") == 0);
1142
1143    lua_getglobal(raw(state), "numbers");
1144    lua_pushinteger(raw(state), 1234);
1145    lua_getglobal(raw(state), "mt");
1146    state.set_metatable(-3);
1147    lua_pop(raw(state), 2);
1148
1149    ATF_REQUIRE(luaL_dostring(raw(state), "return numbers + 2") == 0);
1150    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1151    ATF_REQUIRE_EQ(7, lua_tointeger(raw(state), -1));
1152    lua_pop(raw(state), 1);
1153}
1154
1155
1156ATF_TEST_CASE_WITHOUT_HEAD(set_table__ok);
1157ATF_TEST_CASE_BODY(set_table__ok)
1158{
1159    lutok::state state;
1160    ATF_REQUIRE(luaL_dostring(raw(state), "t = { a = 1, bar = 234 }") == 0);
1161    lua_getglobal(raw(state), "t");
1162
1163    lua_pushstring(raw(state), "bar");
1164    lua_pushstring(raw(state), "baz");
1165    state.set_table();
1166    ATF_REQUIRE_EQ(1, lua_gettop(raw(state)));
1167
1168    lua_pushstring(raw(state), "a");
1169    lua_gettable(raw(state), -2);
1170    ATF_REQUIRE(lua_isnumber(raw(state), -1));
1171    ATF_REQUIRE_EQ(1, lua_tointeger(raw(state), -1));
1172    lua_pop(raw(state), 1);
1173
1174    lua_pushstring(raw(state), "bar");
1175    lua_gettable(raw(state), -2);
1176    ATF_REQUIRE(lua_isstring(raw(state), -1));
1177    ATF_REQUIRE_EQ(std::string("baz"), lua_tostring(raw(state), -1));
1178    lua_pop(raw(state), 1);
1179
1180    lua_pop(raw(state), 1);
1181}
1182
1183
1184ATF_TEST_CASE_WITHOUT_HEAD(set_table__nil);
1185ATF_TEST_CASE_BODY(set_table__nil)
1186{
1187    lutok::state state;
1188    lua_pushnil(raw(state));
1189    lua_pushinteger(raw(state), 1);
1190    lua_pushinteger(raw(state), 2);
1191    REQUIRE_API_ERROR("lua_settable", state.set_table(-3));
1192    lua_pop(raw(state), 3);
1193}
1194
1195
1196ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__top);
1197ATF_TEST_CASE_BODY(to_boolean__top)
1198{
1199    lutok::state state;
1200    lua_pushboolean(raw(state), 1);
1201    ATF_REQUIRE(state.to_boolean());
1202    lua_pushboolean(raw(state), 0);
1203    ATF_REQUIRE(!state.to_boolean());
1204    lua_pop(raw(state), 2);
1205}
1206
1207
1208ATF_TEST_CASE_WITHOUT_HEAD(to_boolean__explicit);
1209ATF_TEST_CASE_BODY(to_boolean__explicit)
1210{
1211    lutok::state state;
1212    lua_pushboolean(raw(state), 0);
1213    lua_pushboolean(raw(state), 1);
1214    ATF_REQUIRE(!state.to_boolean(-2));
1215    ATF_REQUIRE(state.to_boolean(-1));
1216    lua_pop(raw(state), 2);
1217}
1218
1219
1220ATF_TEST_CASE_WITHOUT_HEAD(to_integer__top);
1221ATF_TEST_CASE_BODY(to_integer__top)
1222{
1223    lutok::state state;
1224    lua_pushstring(raw(state), "34");
1225    ATF_REQUIRE_EQ(34, state.to_integer());
1226    lua_pushinteger(raw(state), 12);
1227    ATF_REQUIRE_EQ(12, state.to_integer());
1228    lua_pop(raw(state), 2);
1229}
1230
1231
1232ATF_TEST_CASE_WITHOUT_HEAD(to_integer__explicit);
1233ATF_TEST_CASE_BODY(to_integer__explicit)
1234{
1235    lutok::state state;
1236    lua_pushinteger(raw(state), 12);
1237    lua_pushstring(raw(state), "foobar");
1238    ATF_REQUIRE_EQ(12, state.to_integer(-2));
1239    lua_pop(raw(state), 2);
1240}
1241
1242
1243ATF_TEST_CASE_WITHOUT_HEAD(to_string__top);
1244ATF_TEST_CASE_BODY(to_string__top)
1245{
1246    lutok::state state;
1247    lua_pushstring(raw(state), "foobar");
1248    ATF_REQUIRE_EQ("foobar", state.to_string());
1249    lua_pushinteger(raw(state), 12);
1250    ATF_REQUIRE_EQ("12", state.to_string());
1251    lua_pop(raw(state), 2);
1252}
1253
1254
1255ATF_TEST_CASE_WITHOUT_HEAD(to_string__explicit);
1256ATF_TEST_CASE_BODY(to_string__explicit)
1257{
1258    lutok::state state;
1259    lua_pushstring(raw(state), "foobar");
1260    lua_pushinteger(raw(state), 12);
1261    ATF_REQUIRE_EQ("foobar", state.to_string(-2));
1262    ATF_REQUIRE_EQ("12", state.to_string(-1));
1263    lua_pop(raw(state), 2);
1264}
1265
1266
1267ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__top);
1268ATF_TEST_CASE_BODY(to_userdata__top)
1269{
1270    lutok::state state;
1271    {
1272        int* pointer = static_cast< int* >(
1273            lua_newuserdata(raw(state), sizeof(int)));
1274        *pointer = 987;
1275    }
1276
1277    int* pointer = state.to_userdata< int >();
1278    ATF_REQUIRE_EQ(987, *pointer);
1279    lua_pop(raw(state), 1);
1280}
1281
1282
1283ATF_TEST_CASE_WITHOUT_HEAD(to_userdata__explicit);
1284ATF_TEST_CASE_BODY(to_userdata__explicit)
1285{
1286    lutok::state state;
1287    {
1288        int* pointer = static_cast< int* >(
1289            lua_newuserdata(raw(state), sizeof(int)));
1290        *pointer = 987;
1291    }
1292
1293    lua_pushinteger(raw(state), 3);
1294    int* pointer = state.to_userdata< int >(-2);
1295    ATF_REQUIRE_EQ(987, *pointer);
1296    lua_pop(raw(state), 2);
1297}
1298
1299
1300ATF_TEST_CASE_WITHOUT_HEAD(upvalue_index);
1301ATF_TEST_CASE_BODY(upvalue_index)
1302{
1303    lutok::state state;
1304    lua_pushinteger(raw(state), 25);
1305    lua_pushinteger(raw(state), 30);
1306    lua_pushcclosure(raw(state), c_get_upvalues, 2);
1307    lua_setglobal(raw(state), "c_get_upvalues");
1308
1309    ATF_REQUIRE(luaL_dostring(raw(state),
1310                              "return c_get_upvalues()") == 0);
1311    ATF_REQUIRE_EQ(25, lua_tointeger(raw(state), -2));
1312    ATF_REQUIRE_EQ(30, lua_tointeger(raw(state), -1));
1313    lua_pop(raw(state), 2);
1314}
1315
1316
1317ATF_INIT_TEST_CASES(tcs)
1318{
1319    ATF_ADD_TEST_CASE(tcs, close);
1320    ATF_ADD_TEST_CASE(tcs, get_global__ok);
1321    ATF_ADD_TEST_CASE(tcs, get_global__undefined);
1322    ATF_ADD_TEST_CASE(tcs, get_global_table);
1323    ATF_ADD_TEST_CASE(tcs, get_metafield__ok);
1324    ATF_ADD_TEST_CASE(tcs, get_metafield__undefined);
1325    ATF_ADD_TEST_CASE(tcs, get_metatable__top);
1326    ATF_ADD_TEST_CASE(tcs, get_metatable__explicit);
1327    ATF_ADD_TEST_CASE(tcs, get_metatable__undefined);
1328    ATF_ADD_TEST_CASE(tcs, get_table__ok);
1329    ATF_ADD_TEST_CASE(tcs, get_table__nil);
1330    ATF_ADD_TEST_CASE(tcs, get_table__unknown_index);
1331    ATF_ADD_TEST_CASE(tcs, get_top);
1332    ATF_ADD_TEST_CASE(tcs, insert);
1333    ATF_ADD_TEST_CASE(tcs, is_boolean__empty);
1334    ATF_ADD_TEST_CASE(tcs, is_boolean__top);
1335    ATF_ADD_TEST_CASE(tcs, is_boolean__explicit);
1336    ATF_ADD_TEST_CASE(tcs, is_function__empty);
1337    ATF_ADD_TEST_CASE(tcs, is_function__top);
1338    ATF_ADD_TEST_CASE(tcs, is_function__explicit);
1339    ATF_ADD_TEST_CASE(tcs, is_nil__empty);
1340    ATF_ADD_TEST_CASE(tcs, is_nil__top);
1341    ATF_ADD_TEST_CASE(tcs, is_nil__explicit);
1342    ATF_ADD_TEST_CASE(tcs, is_number__empty);
1343    ATF_ADD_TEST_CASE(tcs, is_number__top);
1344    ATF_ADD_TEST_CASE(tcs, is_number__explicit);
1345    ATF_ADD_TEST_CASE(tcs, is_string__empty);
1346    ATF_ADD_TEST_CASE(tcs, is_string__top);
1347    ATF_ADD_TEST_CASE(tcs, is_string__explicit);
1348    ATF_ADD_TEST_CASE(tcs, is_table__empty);
1349    ATF_ADD_TEST_CASE(tcs, is_table__top);
1350    ATF_ADD_TEST_CASE(tcs, is_table__explicit);
1351    ATF_ADD_TEST_CASE(tcs, is_userdata__empty);
1352    ATF_ADD_TEST_CASE(tcs, is_userdata__top);
1353    ATF_ADD_TEST_CASE(tcs, is_userdata__explicit);
1354    ATF_ADD_TEST_CASE(tcs, load_file__ok);
1355    ATF_ADD_TEST_CASE(tcs, load_file__api_error);
1356    ATF_ADD_TEST_CASE(tcs, load_file__file_not_found_error);
1357    ATF_ADD_TEST_CASE(tcs, load_string__ok);
1358    ATF_ADD_TEST_CASE(tcs, load_string__fail);
1359    ATF_ADD_TEST_CASE(tcs, new_table);
1360    ATF_ADD_TEST_CASE(tcs, new_userdata);
1361    ATF_ADD_TEST_CASE(tcs, next__empty);
1362    ATF_ADD_TEST_CASE(tcs, next__many);
1363    ATF_ADD_TEST_CASE(tcs, open_base);
1364    ATF_ADD_TEST_CASE(tcs, open_string);
1365    ATF_ADD_TEST_CASE(tcs, open_table);
1366    ATF_ADD_TEST_CASE(tcs, pcall__ok);
1367    ATF_ADD_TEST_CASE(tcs, pcall__fail);
1368    ATF_ADD_TEST_CASE(tcs, pop__one);
1369    ATF_ADD_TEST_CASE(tcs, pop__many);
1370    ATF_ADD_TEST_CASE(tcs, push_boolean);
1371    ATF_ADD_TEST_CASE(tcs, push_cxx_closure);
1372    ATF_ADD_TEST_CASE(tcs, push_cxx_function__ok);
1373    ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_exception);
1374    ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_anything);
1375    ATF_ADD_TEST_CASE(tcs, push_cxx_function__fail_overflow);
1376    ATF_ADD_TEST_CASE(tcs, push_integer);
1377    ATF_ADD_TEST_CASE(tcs, push_nil);
1378    ATF_ADD_TEST_CASE(tcs, push_string);
1379    ATF_ADD_TEST_CASE(tcs, push_value__top);
1380    ATF_ADD_TEST_CASE(tcs, push_value__explicit);
1381    ATF_ADD_TEST_CASE(tcs, raw_get__top);
1382    ATF_ADD_TEST_CASE(tcs, raw_get__explicit);
1383    ATF_ADD_TEST_CASE(tcs, raw_set__top);
1384    ATF_ADD_TEST_CASE(tcs, raw_set__explicit);
1385    ATF_ADD_TEST_CASE(tcs, registry_index);
1386    ATF_ADD_TEST_CASE(tcs, set_global);
1387    ATF_ADD_TEST_CASE(tcs, set_metatable__top);
1388    ATF_ADD_TEST_CASE(tcs, set_metatable__explicit);
1389    ATF_ADD_TEST_CASE(tcs, set_table__ok);
1390    ATF_ADD_TEST_CASE(tcs, set_table__nil);
1391    ATF_ADD_TEST_CASE(tcs, to_boolean__top);
1392    ATF_ADD_TEST_CASE(tcs, to_boolean__explicit);
1393    ATF_ADD_TEST_CASE(tcs, to_integer__top);
1394    ATF_ADD_TEST_CASE(tcs, to_integer__explicit);
1395    ATF_ADD_TEST_CASE(tcs, to_string__top);
1396    ATF_ADD_TEST_CASE(tcs, to_string__explicit);
1397    ATF_ADD_TEST_CASE(tcs, to_userdata__top);
1398    ATF_ADD_TEST_CASE(tcs, to_userdata__explicit);
1399    ATF_ADD_TEST_CASE(tcs, upvalue_index);
1400}
1401