1 // Copyright (c) 2004 Daniel Wallin and Arvid Norberg
2 
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
14 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
15 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
16 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
18 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22 
23 #include "test.hpp"
24 
25 #include <luabind/luabind.hpp>
26 
27 using namespace luabind;
28 
29 namespace {
30 
31 struct abstract
32 {
~abstract__anon2ef562d90111::abstract33     virtual ~abstract() {}
34     virtual std::string hello() = 0;
35 };
36 
37 COUNTER_GUARD(abstract);
38 
39 struct concrete : abstract
40 {
hello__anon2ef562d90111::concrete41     std::string hello()
42     {
43         return "test string";
44     }
45 };
46 
47 struct abstract_wrap : abstract, wrap_base
48 {
hello__anon2ef562d90111::abstract_wrap49     std::string hello()
50     {
51         return call_member<std::string>(this, "hello");
52     }
53 };
54 
call_hello(abstract & a)55 static std::string call_hello(abstract& a)
56 {
57     return a.hello();
58 }
59 
return_abstract_ref()60 static abstract& return_abstract_ref()
61 {
62     static concrete c;
63     return c;
64 }
65 
return_const_abstract_ref()66 static abstract const& return_const_abstract_ref()
67 {
68     static concrete c;
69     return c;
70 }
71 
72 } // namespace unnamed
73 
74 
test_main(lua_State * L)75 void test_main(lua_State* L)
76 {
77     module(L)
78     [
79         class_<abstract, abstract_wrap>("abstract")
80             .def(constructor<>())
81             .def("hello", &abstract::hello),
82 
83         def("call_hello", &call_hello),
84           def("return_abstract_ref", &return_abstract_ref),
85           def("return_const_abstract_ref", &return_const_abstract_ref)
86     ];
87 
88     DOSTRING_EXPECTED(L,
89         "x = abstract()\n"
90         "x:hello()\n"
91       , "std::runtime_error: 'Attempt to call nonexistent function'");
92 
93     DOSTRING_EXPECTED(L,
94         "call_hello(x)\n"
95       , "std::runtime_error: 'Attempt to call nonexistent function'");
96 
97     DOSTRING(L,
98         "class 'concrete' (abstract)\n"
99         "  function concrete:__init()\n"
100         "      abstract.__init(self)\n"
101         "  end\n"
102 
103         "  function concrete:hello()\n"
104         "      return 'hello from lua'\n"
105         "  end\n");
106 
107     DOSTRING(L,
108         "y = concrete()\n"
109         "y:hello()\n");
110 
111     DOSTRING(L, "call_hello(y)\n");
112 
113     DOSTRING(L,
114         "x = abstract()\n"
115         "x.hello = function(self) return 'hello from instance' end\n"
116         "print(x.hello)\n"
117         "assert(x:hello() == 'hello from instance')\n"
118         "assert(call_hello(x) == 'hello from instance')\n"
119     );
120 }
121