2021-03-06 23:14:48 +08:00
// sol2
2017-12-20 17:58:32 +08:00
// The MIT License (MIT)
2021-03-06 14:03:23 +08:00
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
2017-12-20 17:58:32 +08:00
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2016-03-15 18:36:25 +08:00
2018-12-20 12:17:15 +08:00
# include "sol_test.hpp"
2017-08-22 03:25:43 +08:00
2021-03-06 14:03:23 +08:00
# include <catch2/catch.hpp>
2017-08-22 03:25:43 +08:00
2016-03-15 18:36:25 +08:00
# include <iostream>
2017-01-10 05:38:23 +08:00
template < typename T >
T va_func ( sol : : variadic_args va , T first ) {
2020-09-26 18:47:20 +08:00
( void ) first ;
2017-01-10 05:38:23 +08:00
T s = 0 ;
for ( auto arg : va ) {
T v = arg ;
s + = v ;
}
return s ;
}
2016-03-15 18:36:25 +08:00
struct A {
2017-09-17 02:18:45 +08:00
int a = 0xA ;
int bark ( ) {
return 1 ;
}
2016-03-15 18:36:25 +08:00
} ;
std : : tuple < int , int > bark ( int num_value , A * a ) {
2016-06-07 03:46:53 +08:00
return std : : tuple < int , int > ( num_value * 2 , a - > bark ( ) ) ;
2016-03-15 18:36:25 +08:00
}
int overloaded ( int x ) {
2016-08-23 01:36:27 +08:00
INFO ( x ) ;
2016-06-07 03:46:53 +08:00
return 3 ;
2016-03-15 18:36:25 +08:00
}
int overloaded ( int x , int y ) {
2016-08-23 01:36:27 +08:00
INFO ( x < < " " < < y ) ;
2016-06-07 03:46:53 +08:00
return 7 ;
2016-03-15 18:36:25 +08:00
}
int overloaded ( int x , int y , int z ) {
2016-08-23 01:36:27 +08:00
INFO ( x < < " " < < y < < " " < < z ) ;
2016-06-07 03:46:53 +08:00
return 11 ;
2016-03-15 18:36:25 +08:00
}
int non_overloaded ( int x , int y , int z ) {
2016-08-23 01:36:27 +08:00
INFO ( x < < " " < < y < < " " < < z ) ;
2016-06-07 03:46:53 +08:00
return 13 ;
2016-03-15 18:36:25 +08:00
}
2016-03-31 04:52:51 +08:00
namespace sep {
2016-06-07 03:46:53 +08:00
int plop_xyz ( int x , int y , std : : string z ) {
2016-08-23 01:36:27 +08:00
INFO ( x < < " " < < y < < " " < < z ) ;
2016-06-07 03:46:53 +08:00
return 11 ;
}
2017-09-17 02:18:45 +08:00
} // namespace sep
2016-03-31 04:52:51 +08:00
2016-05-20 16:20:22 +08:00
int func_1 ( int ) {
2016-06-07 03:46:53 +08:00
return 1 ;
2016-05-20 16:20:22 +08:00
}
std : : string func_1s ( std : : string a ) {
2016-06-07 03:46:53 +08:00
return " string: " + a ;
2016-05-20 16:20:22 +08:00
}
int func_2 ( int , int ) {
2016-06-07 03:46:53 +08:00
return 2 ;
2016-05-20 16:20:22 +08:00
}
void func_3 ( int , int , int ) {
}
2017-09-17 02:18:45 +08:00
int f1 ( int ) {
return 32 ;
}
int f2 ( int , int ) {
return 1 ;
}
2016-06-18 15:32:54 +08:00
struct fer {
double f3 ( int , int ) {
return 2.5 ;
}
} ;
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/tuple returns " , " Make sure tuple returns are ordered properly " ) {
2016-09-26 16:02:03 +08:00
sol : : state lua ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " function f() return '3', 4 end " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-09-26 16:02:03 +08:00
std : : tuple < std : : string , int > result = lua [ " f " ] ( ) ;
auto s = std : : get < 0 > ( result ) ;
auto v = std : : get < 1 > ( result ) ;
REQUIRE ( s = = " 3 " ) ;
REQUIRE ( v = = 4 ) ;
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/overload resolution " , " Check if overloaded function resolution templates compile/work " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2016-06-07 03:46:53 +08:00
lua . open_libraries ( sol : : lib : : base ) ;
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " non_overloaded " , non_overloaded ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " x = non_overloaded(1, 2, 3) \n print(x) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
/*
// Cannot reasonably support: clang++ refuses to try enough
// deductions to make this work
lua . set_function < int > ( " overloaded " , overloaded ) ;
2017-12-07 21:24:50 +08:00
{ auto result = lua . safe_script ( " print(overloaded(1)) " , sol : : script_pass_on_error ) ; REQUIRE ( result . valid ( ) ) ; }
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function < int , int > ( " overloaded " , overloaded ) ;
2017-12-07 21:24:50 +08:00
{ auto result = lua . safe_script ( " print(overloaded(1, 2)) " , sol : : script_pass_on_error ) ; REQUIRE ( result . valid ( ) ) ; }
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function < int , int , int > ( " overloaded " , overloaded ) ;
2017-12-07 21:24:50 +08:00
{ auto result = lua . safe_script ( " print(overloaded(1, 2, 3)) " , sol : : script_pass_on_error ) ; REQUIRE ( result . valid ( ) ) ; }
2016-06-07 03:46:53 +08:00
*/
lua . set_function ( " overloaded " , sol : : resolve < int ( int ) > ( overloaded ) ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " print(overloaded(1)) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " overloaded " , sol : : resolve < int ( int , int ) > ( overloaded ) ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " print(overloaded(1, 2)) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " overloaded " , sol : : resolve < int ( int , int , int ) > ( overloaded ) ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " print(overloaded(1, 2, 3)) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-03-15 18:36:25 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/return order and multi get " , " Check if return order is in the same reading order specified in Lua " ) {
2016-06-07 03:46:53 +08:00
const static std : : tuple < int , int , int > triple = std : : make_tuple ( 10 , 11 , 12 ) ;
const static std : : tuple < int , float > paired = std : : make_tuple ( 10 , 10.f ) ;
sol : : state lua ;
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2019-08-28 06:36:45 +08:00
2019-03-18 19:41:51 +08:00
lua . set_function ( " f " , [ ] { return std : : make_tuple ( 10 , 11 , 12 ) ; } ) ;
2019-08-28 06:36:45 +08:00
lua . set_function ( " h " , [ ] ( ) { return std : : make_tuple ( 10 , 10.0f ) ; } ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " function g() return 10, 11, 12 end \n x,y,z = g() " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
auto tcpp = lua . get < sol : : function > ( " f " ) . call < int , int , int > ( ) ;
auto tlua = lua . get < sol : : function > ( " g " ) . call < int , int , int > ( ) ;
auto tcpp2 = lua . get < sol : : function > ( " h " ) . call < int , float > ( ) ;
auto tluaget = lua . get < int , int , int > ( " x " , " y " , " z " ) ;
REQUIRE ( tcpp = = triple ) ;
REQUIRE ( tlua = = triple ) ;
REQUIRE ( tluaget = = triple ) ;
REQUIRE ( tcpp2 = = paired ) ;
2016-03-15 18:36:25 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/deducing return order and multi get " , " Check if return order is in the same reading order specified in Lua, with regular deducing calls " ) {
2016-06-07 03:46:53 +08:00
const static std : : tuple < int , int , int > triple = std : : make_tuple ( 10 , 11 , 12 ) ;
sol : : state lua ;
lua . set_function ( " f_string " , [ ] ( ) { return " this is a string! " ; } ) ;
sol : : function f_string = lua [ " f_string " ] ;
// Make sure there are no overload collisions / compiler errors for automatic string conversions
std : : string f_string_result = f_string ( ) ;
REQUIRE ( f_string_result = = " this is a string! " ) ;
f_string_result = f_string ( ) ;
REQUIRE ( f_string_result = = " this is a string! " ) ;
2019-08-28 06:36:45 +08:00
lua . set_function ( " f " , [ ] { return std : : make_tuple ( 10 , 11 , 12 ) ; } ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " function g() return 10, 11, 12 end \n x,y,z = g() " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
std : : tuple < int , int , int > tcpp = lua . get < sol : : function > ( " f " ) ( ) ;
std : : tuple < int , int , int > tlua = lua . get < sol : : function > ( " g " ) ( ) ;
std : : tuple < int , int , int > tluaget = lua . get < int , int , int > ( " x " , " y " , " z " ) ;
2016-08-23 01:36:27 +08:00
INFO ( " cpp: " < < std : : get < 0 > ( tcpp ) < < ' , ' < < std : : get < 1 > ( tcpp ) < < ' , ' < < std : : get < 2 > ( tcpp ) ) ;
INFO ( " lua: " < < std : : get < 0 > ( tlua ) < < ' , ' < < std : : get < 1 > ( tlua ) < < ' , ' < < std : : get < 2 > ( tlua ) ) ;
INFO ( " lua xyz: " < < lua . get < int > ( " x " ) < < ' , ' < < lua . get < int > ( " y " ) < < ' , ' < < lua . get < int > ( " z " ) ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( tcpp = = triple ) ;
REQUIRE ( tlua = = triple ) ;
REQUIRE ( tluaget = = triple ) ;
2016-03-15 18:36:25 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/optional values " , " check if optionals can be passed in to be nil or otherwise " ) {
2016-06-07 03:46:53 +08:00
struct thing {
int v ;
} ;
sol : : state lua ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( R " ( function f (a)
2016-03-31 04:52:51 +08:00
return a
2019-08-28 06:36:45 +08:00
end ) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
sol : : function lua_bark = lua [ " f " ] ;
sol : : optional < int > testv = lua_bark ( sol : : optional < int > ( 29 ) ) ;
sol : : optional < int > testn = lua_bark ( sol : : nullopt ) ;
REQUIRE ( ( bool ) testv ) ;
REQUIRE_FALSE ( ( bool ) testn ) ;
REQUIRE ( testv . value ( ) = = 29 ) ;
2020-09-26 18:47:20 +08:00
sol : : optional < thing > v = lua_bark ( sol : : optional < thing > ( thing { 29 } ) ) ;
2019-08-28 06:36:45 +08:00
REQUIRE_NOTHROW ( [ & ] {
sol : : lua_nil_t n = lua_bark ( sol : : nullopt ) ;
return n ;
} ( ) ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( v - > v = = 29 ) ;
2016-03-31 04:52:51 +08:00
}
2019-09-15 12:43:44 +08:00
TEST_CASE ( " functions/pair and tuple and table_proxy tests " , " Check if sol::reference and sol::table_proxy can be passed to functions as arguments " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2019-08-28 06:36:45 +08:00
2019-03-18 19:41:51 +08:00
lua . new_usertype < A > ( " A " , " bark " , & A : : bark ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( R " ( function f (num_value, a)
2016-03-15 18:36:25 +08:00
return num_value * 2 , a : bark ( )
end
2016-03-31 04:52:51 +08:00
function h ( num_value , a , b )
return num_value * 2 , a : bark ( ) , b * 3
end
2019-08-28 06:36:45 +08:00
nested = { variables = { no = { problem = 10 } } } ) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
lua . set_function ( " g " , bark ) ;
sol : : function cpp_bark = lua [ " g " ] ;
sol : : function lua_bark = lua [ " f " ] ;
sol : : function lua_bark2 = lua [ " h " ] ;
2016-03-15 18:36:25 +08:00
2016-06-07 03:46:53 +08:00
sol : : reference lua_variable_x = lua [ " nested " ] [ " variables " ] [ " no " ] [ " problem " ] ;
A cpp_variable_y ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
static const std : : tuple < int , int > abdesired ( 20 , 1 ) ;
static const std : : pair < int , int > cddesired = { 20 , 1 } ;
static const std : : tuple < int , int , int > abcdesired ( 20 , 1 , 3 ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
std : : tuple < int , int > ab = cpp_bark ( lua_variable_x , cpp_variable_y ) ;
std : : pair < int , int > cd = lua_bark ( lua [ " nested " ] [ " variables " ] [ " no " ] [ " problem " ] , cpp_variable_y ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE ( ab = = abdesired ) ;
REQUIRE ( cd = = cddesired ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
ab = cpp_bark ( std : : make_pair ( lua_variable_x , cpp_variable_y ) ) ;
2017-06-08 00:33:59 +08:00
cd = static_cast < std : : pair < int , int > > ( lua_bark ( std : : make_pair ( lua [ " nested " ] [ " variables " ] [ " no " ] [ " problem " ] , cpp_variable_y ) ) ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( ab = = abdesired ) ;
REQUIRE ( cd = = cddesired ) ;
std : : tuple < int , int , int > abc = lua_bark2 ( std : : make_tuple ( 10 , cpp_variable_y ) , sol : : optional < int > ( 1 ) ) ;
REQUIRE ( abc = = abcdesired ) ;
2016-03-15 18:36:25 +08:00
}
2019-08-28 06:36:45 +08:00
TEST_CASE ( " functions/function_result and protected_function_result " ,
" Function result should be the beefy return type for sol::function that allows for error checking and error handlers " ) {
2016-06-07 03:46:53 +08:00
static const char unhandlederrormessage [ ] = " true error message " ;
static const char handlederrormessage [ ] = " doodle " ;
static const std : : string handlederrormessage_s = handlederrormessage ;
2019-03-18 19:41:51 +08:00
sol : : state lua ;
sol : : stack_guard luasg ( lua ) ;
lua . open_libraries ( sol : : lib : : base , sol : : lib : : debug ) ;
2016-06-07 03:46:53 +08:00
// Some function; just using a lambda to be cheap
2019-08-28 06:36:45 +08:00
auto doomfx = [ ] ( ) { throw std : : runtime_error ( unhandlederrormessage ) ; } ;
2016-06-07 03:46:53 +08:00
lua . set_function ( " doom " , doomfx ) ;
auto cpphandlerfx = [ ] ( std : : string x ) {
2016-08-23 01:36:27 +08:00
INFO ( " c++ handler called with: " < < x ) ;
2016-06-07 03:46:53 +08:00
return handlederrormessage ;
} ;
lua . set_function ( " cpphandler " , cpphandlerfx ) ;
2019-08-28 06:36:45 +08:00
auto result1 = lua . safe_script ( std : : string ( " function luahandler ( message ) " ) + " print('lua handler called with: ' .. message) " + " return ' "
+ handlederrormessage + " ' " + " end " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2019-08-28 06:36:45 +08:00
auto nontrampolinefx = [ ] ( lua_State * L ) - > int { return luaL_error ( L , " x " ) ; } ;
2016-06-07 03:46:53 +08:00
lua_CFunction c_nontrampolinefx = nontrampolinefx ;
lua . set ( " nontrampoline " , c_nontrampolinefx ) ;
2019-08-28 06:36:45 +08:00
2017-08-06 07:20:28 +08:00
lua . set_function ( " bark " , [ ] ( ) - > int { return 100 ; } ) ;
2016-06-07 03:46:53 +08:00
2016-10-01 13:27:40 +08:00
sol : : function luahandler = lua [ " luahandler " ] ;
sol : : function cpphandler = lua [ " cpphandler " ] ;
sol : : protected_function doom ( lua [ " doom " ] , luahandler ) ;
2018-06-16 01:19:09 +08:00
sol : : protected_function nontrampoline ( lua [ " nontrampoline " ] , cpphandler ) ;
2016-06-07 03:46:53 +08:00
sol : : protected_function justfine = lua [ " bark " ] ;
sol : : protected_function justfinewithhandler = lua [ " bark " ] ;
2018-06-16 01:19:09 +08:00
2021-01-21 02:55:44 +08:00
justfinewithhandler . set_error_handler ( std : : move ( luahandler ) ) ;
2016-06-07 03:46:53 +08:00
bool present = true ;
{
sol : : protected_function_result result = doom ( ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
present = ( bool ) operr ;
REQUIRE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE_FALSE ( present ) ;
sol : : error err = result ;
REQUIRE ( err . what ( ) = = handlederrormessage_s ) ;
}
{
sol : : protected_function_result result = nontrampoline ( ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
present = ( bool ) operr ;
REQUIRE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE_FALSE ( present ) ;
sol : : error err = result ;
REQUIRE ( err . what ( ) = = handlederrormessage_s ) ;
}
{
sol : : protected_function_result result = justfine ( ) ;
REQUIRE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
present = ( bool ) operr ;
REQUIRE_FALSE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE ( present ) ;
int value = result ;
REQUIRE ( value = = 100 ) ;
}
{
sol : : protected_function_result result = justfinewithhandler ( ) ;
REQUIRE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
present = ( bool ) operr ;
REQUIRE_FALSE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE ( present ) ;
int value = result ;
REQUIRE ( value = = 100 ) ;
}
2016-03-15 18:36:25 +08:00
}
2018-06-16 01:19:09 +08:00
2020-11-20 04:12:56 +08:00
# if SOL_IS_OFF(SOL_COMPILER_VCXX_CLANG_I_) \
& & ( ! defined ( SOL2_CI ) & & ! ( SOL2_CI ) & & ( ( ! defined ( _M_IX86 ) | | defined ( _M_IA64 ) ) | | ( defined ( _WIN64 ) ) | | ( defined ( __LLP64__ ) | | defined ( __LP64__ ) ) ) )
2019-08-28 06:36:45 +08:00
TEST_CASE ( " functions/safe protected_function_result handlers " ,
" These tests will (hopefully) not destroy the stack since they are supposed to be mildly safe. Still, run with caution. " ) {
2018-06-16 01:19:09 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base , sol : : lib : : debug ) ;
static const char unhandlederrormessage [ ] = " true error message " ;
static const char handlederrormessage [ ] = " doodle " ;
static const std : : string handlederrormessage_s = handlederrormessage ;
auto luadoomfx = [ & lua ] ( ) {
// Does not bypass error function, will call it
// however, this bypasses `catch` state
// in trampoline entirely...
luaL_error ( lua . lua_state ( ) , unhandlederrormessage ) ;
} ;
lua . set_function ( " luadoom " , luadoomfx ) ;
auto cpphandlerfx = [ ] ( std : : string x ) {
INFO ( " c++ handler called with: " < < x ) ;
return handlederrormessage ;
} ;
lua . set_function ( " cpphandler " , cpphandlerfx ) ;
sol : : function cpphandler = lua [ " cpphandler " ] ;
sol : : protected_function luadoom ( lua [ " luadoom " ] ) ;
2021-01-21 02:55:44 +08:00
luadoom . set_error_handler ( cpphandler ) ;
2019-01-14 10:46:53 +08:00
2018-06-16 01:19:09 +08:00
bool present = true ;
{
sol : : protected_function_result result = luadoom ( ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
present = ( bool ) operr ;
REQUIRE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE_FALSE ( present ) ;
sol : : error err = result ;
REQUIRE ( err . what ( ) = = handlederrormessage_s ) ;
}
2019-01-14 10:46:53 +08:00
}
TEST_CASE ( " functions/unsafe protected_function_result handlers " ,
" This test will thrash the stack and allocations on weaker compilers (e.g., non 64-bit ones). Run with caution. " ) {
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base , sol : : lib : : debug ) ;
static const char handlederrormessage [ ] = " doodle " ;
static const std : : string handlederrormessage_s = handlederrormessage ;
auto cpphandlerfx = [ ] ( std : : string x ) {
INFO ( " c++ handler called with: " < < x ) ;
return handlederrormessage ;
} ;
lua . set_function ( " cpphandler " , cpphandlerfx ) ;
2020-11-20 04:12:56 +08:00
auto nontrampolinefx = [ ] ( lua_State * ) noexcept ( false ) - > int {
2019-01-14 10:46:53 +08:00
// this code shoots an exception
// through the C API, without the trampoline
// present.
// it is probably guaranteed to kill our code.
throw " x " ;
} ;
lua_CFunction c_nontrampolinefx = nontrampolinefx ;
lua . set ( " nontrampoline " , c_nontrampolinefx ) ;
sol : : function cpphandler = lua [ " cpphandler " ] ;
sol : : protected_function nontrampoline = lua [ " nontrampoline " ] ;
2021-01-21 02:55:44 +08:00
nontrampoline . set_error_handler ( std : : move ( cpphandler ) ) ;
2019-01-14 10:46:53 +08:00
2018-06-16 01:19:09 +08:00
{
sol : : protected_function_result result = nontrampoline ( ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
sol : : optional < sol : : error > operr = result ;
sol : : optional < int > opvalue = result ;
2019-01-14 10:46:53 +08:00
bool present = ( bool ) operr ;
2018-06-16 01:19:09 +08:00
REQUIRE ( present ) ;
present = ( bool ) opvalue ;
REQUIRE_FALSE ( present ) ;
sol : : error err = result ;
2020-12-17 04:25:35 +08:00
# if SOL_IS_ON(SOL_USE_LUAJIT_I_)
# if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
2019-03-24 00:09:51 +08:00
REQUIRE ( err . what ( ) = = std : : string ( " C++ exception " ) ) ;
# else
2018-06-16 01:19:09 +08:00
REQUIRE ( err . what ( ) = = handlederrormessage_s ) ;
2019-03-24 00:09:51 +08:00
# endif
# else
REQUIRE ( err . what ( ) = = handlederrormessage_s ) ;
# endif
2018-06-16 01:19:09 +08:00
}
}
2019-01-14 10:46:53 +08:00
# endif // These tests will thrash the stack and allocations on weaker compilers
2016-03-15 18:36:25 +08:00
2017-07-10 00:00:57 +08:00
TEST_CASE ( " functions/all kinds " , " Register all kinds of functions, make sure they all compile and work " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2016-06-07 03:46:53 +08:00
struct test_1 {
int a = 0xA ;
virtual int bark ( ) {
return a ;
}
int bark_mem ( ) {
return a ;
}
static std : : tuple < int , int > x_bark ( int num_value , test_1 * a ) {
return std : : tuple < int , int > ( num_value * 2 , a - > a ) ;
}
2019-03-23 04:28:17 +08:00
virtual ~ test_1 ( ) {
}
2016-06-07 03:46:53 +08:00
} ;
struct test_2 {
int a = 0xC ;
int bark ( ) {
return 20 ;
}
} ;
struct inner {
const int z = 5653 ;
} ;
struct nested {
inner i ;
} ;
auto a = [ ] ( ) { return 500 ; } ;
auto b = [ & ] ( ) { return 501 ; } ;
auto c = [ & ] ( ) { return 502 ; } ;
auto d = [ ] ( ) { return 503 ; } ;
2019-08-28 06:36:45 +08:00
lua . new_usertype < test_1 > ( " test_1 " , " bark " , sol : : c_call < decltype ( & test_1 : : bark_mem ) , & test_1 : : bark_mem > ) ;
lua . new_usertype < test_2 > ( " test_2 " , " bark " , sol : : c_call < decltype ( & test_2 : : bark ) , & test_2 : : bark > ) ;
2016-06-07 03:46:53 +08:00
test_2 t2 ;
lua . set_function ( " a " , a ) ;
lua . set_function ( " b " , b ) ;
lua . set_function ( " c " , std : : ref ( c ) ) ;
lua . set_function ( " d " , std : : ref ( d ) ) ;
lua . set_function ( " f " , & test_1 : : bark ) ;
lua . set_function ( " g " , test_1 : : x_bark ) ;
lua . set_function ( " h " , sol : : c_call < decltype ( & test_1 : : bark_mem ) , & test_1 : : bark_mem > ) ;
lua . set_function ( " i " , & test_2 : : bark , test_2 ( ) ) ;
lua . set_function ( " j " , & test_2 : : a , test_2 ( ) ) ;
lua . set_function ( " k " , & test_2 : : a ) ;
lua . set_function ( " l " , sol : : c_call < decltype ( & test_1 : : a ) , & test_1 : : a > ) ;
lua . set_function ( " m " , & test_2 : : a , & t2 ) ;
lua . set_function ( " n " , sol : : c_call < decltype ( & non_overloaded ) , & non_overloaded > ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
o1 = test_1 . new ( )
o2 = test_2 . new ( )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2016-03-30 12:31:18 +08:00
2018-01-29 11:21:13 +08:00
auto result2 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
ob = o1 : bark ( )
A = a ( )
B = b ( )
C = c ( )
D = d ( )
F = f ( o1 )
G0 , G1 = g ( 2 , o1 )
H = h ( o1 )
I = i ( o1 )
I = i ( o1 )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result2 . valid ( ) ) ;
2016-03-30 12:31:18 +08:00
2018-01-29 11:21:13 +08:00
auto result3 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
J0 = j ( )
j ( 24 )
J1 = j ( )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result3 . valid ( ) ) ;
2016-03-30 12:31:18 +08:00
2018-01-29 11:21:13 +08:00
auto result4 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
K0 = k ( o2 )
k ( o2 , 1024 )
K1 = k ( o2 )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result4 . valid ( ) ) ;
2016-03-30 12:31:18 +08:00
2018-01-29 11:21:13 +08:00
auto result5 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
L0 = l ( o1 )
l ( o1 , 678 )
L1 = l ( o1 )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result5 . valid ( ) ) ;
2016-03-30 12:31:18 +08:00
2018-01-29 11:21:13 +08:00
auto result6 = lua . safe_script ( R " (
2016-03-30 12:31:18 +08:00
M0 = m ( )
m ( 256 )
M1 = m ( )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result6 . valid ( ) ) ;
2016-04-07 17:53:33 +08:00
2018-01-29 11:21:13 +08:00
auto result7 = lua . safe_script ( R " (
2016-04-07 17:53:33 +08:00
N = n ( 1 , 2 , 3 )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result7 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
int ob , A , B , C , D , F , G0 , G1 , H , I , J0 , J1 , K0 , K1 , L0 , L1 , M0 , M1 , N ;
std : : tie ( ob , A , B , C , D , F , G0 , G1 , H , I , J0 , J1 , K0 , K1 , L0 , L1 , M0 , M1 , N )
2019-08-28 06:36:45 +08:00
= lua . get < int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int > (
" ob " , " A " , " B " , " C " , " D " , " F " , " G0 " , " G1 " , " H " , " I " , " J0 " , " J1 " , " K0 " , " K1 " , " L0 " , " L1 " , " M0 " , " M1 " , " N " ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( ob = = 0xA ) ;
REQUIRE ( A = = 500 ) ;
REQUIRE ( B = = 501 ) ;
REQUIRE ( C = = 502 ) ;
REQUIRE ( D = = 503 ) ;
REQUIRE ( F = = 0xA ) ;
REQUIRE ( G0 = = 4 ) ;
REQUIRE ( G1 = = 0xA ) ;
REQUIRE ( H = = 0xA ) ;
REQUIRE ( I = = 20 ) ;
REQUIRE ( J0 = = 0xC ) ;
REQUIRE ( J1 = = 24 ) ;
REQUIRE ( K0 = = 0xC ) ;
REQUIRE ( K1 = = 1024 ) ;
REQUIRE ( L0 = = 0xA ) ;
REQUIRE ( L1 = = 678 ) ;
REQUIRE ( M0 = = 0xC ) ;
REQUIRE ( M1 = = 256 ) ;
REQUIRE ( N = = 13 ) ;
sol : : tie ( ob , A , B , C , D , F , G0 , G1 , H , I , J0 , J1 , K0 , K1 , L0 , L1 , M0 , M1 , N )
2019-08-28 06:36:45 +08:00
= lua . get < int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int , int > (
" ob " , " A " , " B " , " C " , " D " , " F " , " G0 " , " G1 " , " H " , " I " , " J0 " , " J1 " , " K0 " , " K1 " , " L0 " , " L1 " , " M0 " , " M1 " , " N " ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( ob = = 0xA ) ;
REQUIRE ( A = = 500 ) ;
REQUIRE ( B = = 501 ) ;
REQUIRE ( C = = 502 ) ;
REQUIRE ( D = = 503 ) ;
REQUIRE ( F = = 0xA ) ;
REQUIRE ( G0 = = 4 ) ;
REQUIRE ( G1 = = 0xA ) ;
REQUIRE ( H = = 0xA ) ;
REQUIRE ( I = = 20 ) ;
REQUIRE ( J0 = = 0xC ) ;
REQUIRE ( J1 = = 24 ) ;
REQUIRE ( K0 = = 0xC ) ;
REQUIRE ( K1 = = 1024 ) ;
REQUIRE ( L0 = = 0xA ) ;
REQUIRE ( L1 = = 678 ) ;
REQUIRE ( M0 = = 0xC ) ;
REQUIRE ( M1 = = 256 ) ;
REQUIRE ( N = = 13 ) ;
// Work that compiler, WORK IT!
2019-01-14 10:46:53 +08:00
test_2 test_2_instance ;
2016-06-07 03:46:53 +08:00
lua . set ( " o " , & test_1 : : bark ) ;
lua . set ( " p " , test_1 : : x_bark ) ;
lua . set ( " q " , sol : : c_call < decltype ( & test_1 : : bark_mem ) , & test_1 : : bark_mem > ) ;
lua . set ( " r " , & test_2 : : a ) ;
lua . set ( " s " , sol : : readonly ( & test_2 : : a ) ) ;
lua . set_function ( " t " , sol : : readonly ( & test_2 : : a ) , test_2 ( ) ) ;
2019-01-14 10:46:53 +08:00
lua . set_function ( " t2 " , sol : : readonly ( & test_2 : : a ) , & test_2_instance ) ;
lua . set_function ( " t3 " , sol : : readonly ( & test_2 : : a ) , std : : ref ( test_2_instance ) ) ;
lua . set_function ( " t4 " , sol : : readonly ( & test_2 : : a ) , std : : cref ( test_2_instance ) ) ;
2016-06-07 03:46:53 +08:00
lua . set_function ( " u " , & nested : : i , nested ( ) ) ;
lua . set ( " v " , & nested : : i ) ;
lua . set ( " nested " , nested ( ) ) ;
lua . set ( " inner " , inner ( ) ) ;
2017-08-11 15:24:17 +08:00
{
auto result = lua . safe_script ( " s(o2, 2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
}
{
2019-02-11 04:02:40 +08:00
auto tresult = lua . safe_script ( " t(2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( tresult . valid ( ) ) ;
auto tresult2 = lua . safe_script ( " t2(2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( tresult2 . valid ( ) ) ;
auto tresult3 = lua . safe_script ( " t3(2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( tresult3 . valid ( ) ) ;
auto tresult4 = lua . safe_script ( " t4(2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( tresult4 . valid ( ) ) ;
2017-08-11 15:24:17 +08:00
}
{
auto result = lua . safe_script ( " u(inner) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " v(nested, inner) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-09-17 02:18:45 +08:00
}
2016-03-30 12:31:18 +08:00
}
2016-03-31 04:52:51 +08:00
2017-07-10 00:00:57 +08:00
TEST_CASE ( " simple/call with parameters " , " Lua function is called with a few parameters from C++ " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " function my_add(i, j, k) return i + j + k end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-06-07 03:46:53 +08:00
auto f = lua . get < sol : : function > ( " my_add " ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " function my_nothing(i, j, k) end " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2016-06-07 03:46:53 +08:00
auto fvoid = lua . get < sol : : function > ( " my_nothing " ) ;
2019-08-28 06:36:45 +08:00
REQUIRE_NOTHROW ( [ & ] ( ) { fvoid ( 1 , 2 , 3 ) ; } ( ) ) ;
2017-08-11 15:24:17 +08:00
REQUIRE_NOTHROW ( [ & ] ( ) {
int a = f . call < int > ( 1 , 2 , 3 ) ;
REQUIRE ( a = = 6 ) ;
} ( ) ) ;
sol : : protected_function pf = f ;
REQUIRE_NOTHROW ( [ & ] ( ) {
sol : : protected_function_result pfr = pf ( 1 , 2 , " arf " ) ;
REQUIRE_FALSE ( pfr . valid ( ) ) ;
} ( ) ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " simple/call c++ function " , " C++ function is called from lua " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " plop_xyz " , sep : : plop_xyz ) ;
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " x = plop_xyz(2, 6, 'hello') " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE ( lua . get < int > ( " x " ) = = 11 ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " simple/call lambda " , " A C++ lambda is exposed to lua and called " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
int a = 0 ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " foo " , [ & a ] { a = 1 ; } ) ;
2016-03-31 04:52:51 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " foo() " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE ( a = = 1 ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " advanced/get and call " , " Checks for lambdas returning values after a get operation " ) {
2016-06-07 03:46:53 +08:00
const static std : : string lol = " lol " , str = " str " ;
const static std : : tuple < int , float , double , std : : string > heh_tuple = std : : make_tuple ( 1 , 6.28f , 3.14 , std : : string ( " heh " ) ) ;
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " a " , [ ] { return 42 ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " a " ) . call < int > ( ) = = 42 ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " b " , [ ] { return 42u ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " b " ) . call < unsigned int > ( ) = = 42u ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " c " , [ ] { return 3.14 ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " c " ) . call < double > ( ) = = 3.14 ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " d " , [ ] { return 6.28f ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " d " ) . call < float > ( ) = = 6.28f ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " e " , [ ] { return " lol " ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " e " ) . call < std : : string > ( ) = = lol ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " f " , [ ] { return true ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " f " ) . call < bool > ( ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " g " , [ ] { return std : : string ( " str " ) ; } ) ) ;
REQUIRE ( lua . get < sol : : function > ( " g " ) . call < std : : string > ( ) = = str ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " h " , [ ] { } ) ) ;
REQUIRE_NOTHROW ( lua . get < sol : : function > ( " h " ) . call ( ) ) ;
2016-03-31 04:52:51 +08:00
2017-09-22 19:30:41 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " i " , [ ] { return sol : : lua_nil ; } ) ) ;
2017-09-22 23:04:46 +08:00
REQUIRE ( lua . get < sol : : function > ( " i " ) . call < sol : : lua_nil_t > ( ) = = sol : : lua_nil ) ;
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " j " , [ ] { return std : : make_tuple ( 1 , 6.28f , 3.14 , std : : string ( " heh " ) ) ; } ) ) ;
REQUIRE ( ( lua . get < sol : : function > ( " j " ) . call < int , float , double , std : : string > ( ) = = heh_tuple ) ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " advanced/operator[] call " , " Checks for lambdas returning values using operator[] " ) {
2016-06-07 03:46:53 +08:00
const static std : : string lol = " lol " , str = " str " ;
const static std : : tuple < int , float , double , std : : string > heh_tuple = std : : make_tuple ( 1 , 6.28f , 3.14 , std : : string ( " heh " ) ) ;
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " a " , [ ] { return 42 ; } ) ) ;
REQUIRE ( lua [ " a " ] . call < int > ( ) = = 42 ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " b " , [ ] { return 42u ; } ) ) ;
REQUIRE ( lua [ " b " ] . call < unsigned int > ( ) = = 42u ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " c " , [ ] { return 3.14 ; } ) ) ;
REQUIRE ( lua [ " c " ] . call < double > ( ) = = 3.14 ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " d " , [ ] { return 6.28f ; } ) ) ;
REQUIRE ( lua [ " d " ] . call < float > ( ) = = 6.28f ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " e " , [ ] { return " lol " ; } ) ) ;
REQUIRE ( lua [ " e " ] . call < std : : string > ( ) = = lol ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " f " , [ ] { return true ; } ) ) ;
REQUIRE ( lua [ " f " ] . call < bool > ( ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " g " , [ ] { return std : : string ( " str " ) ; } ) ) ;
REQUIRE ( lua [ " g " ] . call < std : : string > ( ) = = str ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " h " , [ ] { } ) ) ;
REQUIRE_NOTHROW ( lua [ " h " ] . call ( ) ) ;
2016-03-31 04:52:51 +08:00
2017-09-22 19:30:41 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " i " , [ ] { return sol : : lua_nil ; } ) ) ;
2017-09-22 23:04:46 +08:00
REQUIRE ( lua [ " i " ] . call < sol : : lua_nil_t > ( ) = = sol : : lua_nil ) ;
2016-06-07 03:46:53 +08:00
REQUIRE_NOTHROW ( lua . set_function ( " j " , [ ] { return std : : make_tuple ( 1 , 6.28f , 3.14 , std : : string ( " heh " ) ) ; } ) ) ;
REQUIRE ( ( lua [ " j " ] . call < int , float , double , std : : string > ( ) = = heh_tuple ) ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " advanced/call lambdas " , " A C++ lambda is exposed to lua and called " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
int x = 0 ;
lua . set_function ( " set_x " , [ & ] ( int new_x ) {
x = new_x ;
return 0 ;
} ) ;
2016-03-31 04:52:51 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( " set_x(9) " , sol : : script_pass_on_error ) ;
REQUIRE ( result1 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
REQUIRE ( x = = 9 ) ;
2016-03-31 04:52:51 +08:00
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " advanced/call referenced obj " , " A C++ object is passed by pointer/reference_wrapper to lua and invoked " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
int x = 0 ;
auto objx = [ & ] ( int new_x ) {
x = new_x ;
return 0 ;
} ;
lua . set_function ( " set_x " , std : : ref ( objx ) ) ;
2016-03-31 04:52:51 +08:00
2016-06-07 03:46:53 +08:00
int y = 0 ;
auto objy = [ & ] ( int new_y ) {
y = new_y ;
return std : : tuple < int , int > ( 0 , 0 ) ;
} ;
lua . set_function ( " set_y " , & decltype ( objy ) : : operator ( ) , std : : ref ( objy ) ) ;
2016-03-31 04:52:51 +08:00
2020-12-18 12:25:48 +08:00
sol : : optional < sol : : error > result1 = lua . safe_script ( " set_x(9) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result1 . has_value ( ) ) ;
sol : : optional < sol : : error > result2 = lua . safe_script ( " set_y(9) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result2 . has_value ( ) ) ;
2018-01-29 11:21:13 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE ( x = = 9 ) ;
REQUIRE ( y = = 9 ) ;
2016-03-31 04:52:51 +08:00
}
2016-04-01 04:16:07 +08:00
2016-04-24 22:09:05 +08:00
TEST_CASE ( " functions/tie " , " make sure advanced syntax with 'tie' works " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
2016-04-01 04:16:07 +08:00
2018-01-29 11:21:13 +08:00
auto result1 = lua . safe_script ( R " (function f ()
2016-04-01 04:16:07 +08:00
return 1 , 2 , 3
2019-08-28 06:36:45 +08:00
end ) " ,
sol : : script_pass_on_error ) ;
2018-01-29 11:21:13 +08:00
REQUIRE ( result1 . valid ( ) ) ;
2016-06-07 03:46:53 +08:00
sol : : function f = lua [ " f " ] ;
2016-04-01 04:16:07 +08:00
2016-06-07 03:46:53 +08:00
int a , b , c ;
sol : : tie ( a , b , c ) = f ( ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
2016-04-01 04:16:07 +08:00
}
2016-04-17 14:18:34 +08:00
2016-05-20 16:20:22 +08:00
TEST_CASE ( " functions/overloading " , " Check if overloading works properly for regular set function syntax " ) {
2016-06-07 03:46:53 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
2016-05-20 16:20:22 +08:00
2016-06-07 03:46:53 +08:00
lua . set_function ( " func_1 " , func_1 ) ;
2016-07-08 04:52:39 +08:00
lua . set_function ( " func " , sol : : overload ( func_2 , func_3 , func_1 , func_1s ) ) ;
2016-05-20 16:20:22 +08:00
2016-06-07 03:46:53 +08:00
const std : : string string_bark = " string: bark " ;
2016-05-20 16:20:22 +08:00
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script (
2019-08-28 06:36:45 +08:00
" a = func(1) \n "
" b = func('bark') \n "
" c = func(1,2) \n "
" func(1,2,3) \n " ,
sol : : script_pass_on_error ) ;
2017-12-07 21:24:50 +08:00
REQUIRE ( result . valid ( ) ) ;
}
2016-05-20 16:20:22 +08:00
2016-06-07 03:46:53 +08:00
REQUIRE ( ( lua [ " a " ] = = 1 ) ) ;
REQUIRE ( ( lua [ " b " ] = = string_bark ) ) ;
REQUIRE ( ( lua [ " c " ] = = 2 ) ) ;
2016-05-20 16:20:22 +08:00
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " func(1,2,'meow') " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
}
2016-05-20 16:20:22 +08:00
}
2016-06-18 15:32:54 +08:00
TEST_CASE ( " overloading/c_call " , " Make sure that overloading works with c_call functionality " ) {
sol : : state lua ;
lua . set ( " f " , sol : : c_call < sol : : wrap < decltype ( & f1 ) , & f1 > , sol : : wrap < decltype ( & f2 ) , & f2 > , sol : : wrap < decltype ( & fer : : f3 ) , & fer : : f3 > > ) ;
lua . set ( " g " , sol : : c_call < sol : : wrap < decltype ( & f1 ) , & f1 > > ) ;
lua . set ( " h " , sol : : c_call < decltype ( & f2 ) , & f2 > ) ;
lua . set ( " obj " , fer ( ) ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " r1 = f(1) " ) ;
lua . safe_script ( " r2 = f(1, 2) " ) ;
lua . safe_script ( " r3 = f(obj, 1, 2) " ) ;
lua . safe_script ( " r4 = g(1) " ) ;
lua . safe_script ( " r5 = h(1, 2) " ) ;
2016-06-18 15:32:54 +08:00
int r1 = lua [ " r1 " ] ;
int r2 = lua [ " r2 " ] ;
double r3 = lua [ " r3 " ] ;
int r4 = lua [ " r4 " ] ;
int r5 = lua [ " r5 " ] ;
REQUIRE ( r1 = = 32 ) ;
REQUIRE ( r2 = = 1 ) ;
REQUIRE ( r3 = = 2.5 ) ;
REQUIRE ( r4 = = 32 ) ;
REQUIRE ( r5 = = 1 ) ;
}
2016-10-05 11:37:08 +08:00
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/stack atomic " , " make sure functions don't impede on the stack " ) {
2019-08-28 06:36:45 +08:00
// setup sol/lua
2016-10-05 11:37:08 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base , sol : : lib : : string ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " function ErrorHandler(msg) print('Lua created error msg : ' .. msg) return msg end " ) ;
lua . safe_script ( " function stringtest(a) if a == nil then error('fuck') end print('Lua recieved content : ' .. a) return a end " ) ;
2016-10-05 11:37:08 +08:00
// test normal function
{
sol : : stack_guard normalsg ( lua ) ;
std : : string str = lua [ " stringtest " ] ( " normal test " ) ;
INFO ( " Back in C++, direct call result is : " < < str ) ;
}
2019-08-28 06:36:45 +08:00
// test protected_function
2016-10-05 11:37:08 +08:00
sol : : protected_function Stringtest ( lua [ " stringtest " ] ) ;
2021-01-21 02:55:44 +08:00
Stringtest . set_error_handler ( lua [ " ErrorHandler " ] ) ;
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2016-10-05 11:37:08 +08:00
{
sol : : protected_function_result stringresult = Stringtest ( " protected test " ) ;
REQUIRE ( stringresult . valid ( ) ) ;
std : : string s = stringresult ;
INFO ( " Back in C++, protected result is : " < < s ) ;
}
2019-03-18 19:41:51 +08:00
REQUIRE ( luasg . check_stack ( ) ) ;
2016-10-05 11:37:08 +08:00
2019-08-28 06:36:45 +08:00
// test optional
2016-10-05 11:37:08 +08:00
{
sol : : stack_guard opsg ( lua ) ;
sol : : optional < std : : string > opt_result = Stringtest ( " optional test " ) ;
REQUIRE ( opsg . check_stack ( ) ) ;
2017-09-17 02:18:45 +08:00
if ( opt_result ) {
2016-10-05 11:37:08 +08:00
std : : string s = opt_result . value ( ) ;
INFO ( " Back in C++, opt_result is : " < < s ) ;
}
2017-09-17 02:18:45 +08:00
else {
2016-10-05 11:37:08 +08:00
INFO ( " opt_result failed " ) ;
}
}
2019-03-18 19:41:51 +08:00
REQUIRE ( luasg . check_stack ( ) ) ;
2016-10-05 11:37:08 +08:00
{
2017-09-22 19:30:41 +08:00
sol : : protected_function_result errresult = Stringtest ( sol : : lua_nil ) ;
2016-10-05 11:37:08 +08:00
REQUIRE_FALSE ( errresult . valid ( ) ) ;
sol : : error err = errresult ;
std : : string msg = err . what ( ) ;
INFO ( " error : " < < msg ) ;
}
2019-03-18 19:41:51 +08:00
REQUIRE ( luasg . check_stack ( ) ) ;
2016-10-05 11:37:08 +08:00
}
2016-11-23 15:39:52 +08:00
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/stack multi-return " , " Make sure the stack is protected after multi-returns " ) {
2016-11-26 16:32:28 +08:00
sol : : state lua ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " function f () return 1, 2, 3, 4, 5 end " ) ;
2016-11-26 16:32:28 +08:00
{
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2016-11-26 16:32:28 +08:00
sol : : stack : : push ( lua , double ( 256.78 ) ) ;
{
int a , b , c , d , e ;
sol : : stack_guard sg2 ( lua ) ;
sol : : function f = lua [ " f " ] ;
sol : : tie ( a , b , c , d , e ) = f ( ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
REQUIRE ( d = = 4 ) ;
REQUIRE ( e = = 5 ) ;
}
double f = sol : : stack : : pop < double > ( lua ) ;
REQUIRE ( f = = 256.78 ) ;
}
}
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/protected stack multi-return " , " Make sure the stack is protected after multi-returns " ) {
2016-11-26 16:32:28 +08:00
sol : : state lua ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " function f () return 1, 2, 3, 4, 5 end " ) ;
2016-11-26 16:32:28 +08:00
{
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2016-11-26 16:32:28 +08:00
sol : : stack : : push ( lua , double ( 256.78 ) ) ;
{
int a , b , c , d , e ;
sol : : stack_guard sg2 ( lua ) ;
sol : : protected_function pf = lua [ " f " ] ;
sol : : tie ( a , b , c , d , e ) = pf ( ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
REQUIRE ( d = = 4 ) ;
REQUIRE ( e = = 5 ) ;
}
double f = sol : : stack : : pop < double > ( lua ) ;
REQUIRE ( f = = 256.78 ) ;
}
}
2017-01-10 05:38:23 +08:00
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/function_result as arguments " , " ensure that function_result can be pushed as its results and not a userdata " ) {
sol : : state lua ;
lua . open_libraries ( ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " function f () return 1, 2, 3, 4, 5 end " ) ;
lua . safe_script ( " function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end " ) ;
2017-08-06 07:20:28 +08:00
{
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2017-08-06 07:20:28 +08:00
sol : : stack : : push ( lua , double ( 256.78 ) ) ;
{
int a , b , c , d , e ;
sol : : stack_guard sg2 ( lua ) ;
sol : : function pf = lua [ " f " ] ;
sol : : tie ( a , b , c , d , e ) = pf ( ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
REQUIRE ( d = = 4 ) ;
REQUIRE ( e = = 5 ) ;
2019-08-28 06:36:45 +08:00
REQUIRE_NOTHROW ( [ & ] ( ) { lua [ " g " ] ( pf ( ) ) ; } ( ) ) ;
2017-08-06 07:20:28 +08:00
}
double f = sol : : stack : : pop < double > ( lua ) ;
REQUIRE ( f = = 256.78 ) ;
}
}
TEST_CASE ( " functions/protected_function_result as arguments " , " ensure that protected_function_result can be pushed as its results and not a userdata " ) {
sol : : state lua ;
lua . open_libraries ( ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " function f () return 1, 2, 3, 4, 5 end " ) ;
lua . safe_script ( " function g (a, b, c, d, e) assert(a == 1) assert(b == 2) assert(c == 3) assert(d == 4) assert(e == 5) end " ) ;
2017-08-06 07:20:28 +08:00
{
2019-03-18 19:41:51 +08:00
sol : : stack_guard luasg ( lua ) ;
2017-08-06 07:20:28 +08:00
sol : : stack : : push ( lua , double ( 256.78 ) ) ;
{
int a , b , c , d , e ;
sol : : stack_guard sg2 ( lua ) ;
sol : : protected_function pf = lua [ " f " ] ;
sol : : tie ( a , b , c , d , e ) = pf ( ) ;
REQUIRE ( a = = 1 ) ;
REQUIRE ( b = = 2 ) ;
REQUIRE ( c = = 3 ) ;
REQUIRE ( d = = 4 ) ;
REQUIRE ( e = = 5 ) ;
2019-08-28 06:36:45 +08:00
REQUIRE_NOTHROW ( [ & ] ( ) { lua [ " g " ] ( pf ( ) ) ; } ( ) ) ;
2017-08-06 07:20:28 +08:00
}
double f = sol : : stack : : pop < double > ( lua ) ;
REQUIRE ( f = = 256.78 ) ;
}
}
TEST_CASE ( " functions/overloaded variadic " , " make sure variadics work to some degree with overloading " ) {
2017-01-10 05:38:23 +08:00
sol : : state lua ;
lua . open_libraries ( ) ;
sol : : table ssl = lua . create_named_table ( " ssl " ) ;
ssl . set_function ( " test " , sol : : overload ( & va_func < int > , & va_func < double > ) ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " a = ssl.test(1, 2, 3) " ) ;
lua . safe_script ( " b = ssl.test(1, 2) " ) ;
lua . safe_script ( " c = ssl.test(2.2) " ) ;
2017-01-10 05:38:23 +08:00
int a = lua [ " a " ] ;
int b = lua [ " b " ] ;
double c = lua [ " c " ] ;
REQUIRE ( a = = 6 ) ;
REQUIRE ( b = = 3 ) ;
REQUIRE ( c = = 2.2 ) ;
}
2017-05-16 18:12:28 +08:00
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/sectioning variadic " , " make sure variadics can bite off chunks of data " ) {
2017-07-01 23:02:15 +08:00
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . set_function ( " f " , [ ] ( sol : : variadic_args va ) {
int r = 0 ;
sol : : variadic_args shifted_va ( va . lua_state ( ) , 3 ) ;
for ( auto v : shifted_va ) {
int value = v ;
r + = value ;
}
return r ;
} ) ;
2017-08-22 03:25:43 +08:00
lua . safe_script ( " x = f(1, 2, 3, 4) " ) ;
lua . safe_script ( " x2 = f(8, 200, 3, 4) " ) ;
lua . safe_script ( " x3 = f(1, 2, 3, 4, 5, 6) " ) ;
2017-07-01 23:02:15 +08:00
2017-08-22 03:25:43 +08:00
lua . safe_script ( " print(x) assert(x == 7) " ) ;
lua . safe_script ( " print(x2) assert(x2 == 7) " ) ;
lua . safe_script ( " print(x3) assert(x3 == 18) " ) ;
2017-07-01 23:02:15 +08:00
}
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/pointer nullptr + nil " , " ensure specific semantics for handling pointer-nils passed through sol " ) {
2017-07-01 06:18:25 +08:00
struct nil_test {
static void f ( nil_test * p ) {
REQUIRE ( p = = nullptr ) ;
}
static void g ( std : : unique_ptr < nil_test > & p ) {
REQUIRE ( p = = nullptr ) ;
}
static void h ( std : : shared_ptr < nil_test > & p ) {
REQUIRE ( p = = nullptr ) ;
}
} ;
2017-09-17 02:18:45 +08:00
2017-07-01 06:18:25 +08:00
std : : shared_ptr < nil_test > sptr ;
std : : unique_ptr < nil_test > uptr ;
std : : unique_ptr < nil_test > ruptr ;
nil_test * rptr = ruptr . get ( ) ;
nil_test * vptr = nullptr ;
SECTION ( " ptr " ) {
sol : : state lua ;
lua [ " v1 " ] = sptr ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
lua [ " v3 " ] = rptr ;
lua [ " v4 " ] = vptr ;
REQUIRE_NOTHROW ( [ & ] ( ) {
nil_test * v1 = lua [ " v1 " ] ;
nil_test * v2 = lua [ " v2 " ] ;
nil_test * v3 = lua [ " v3 " ] ;
nil_test * v4 = lua [ " v4 " ] ;
REQUIRE ( v1 = = sptr . get ( ) ) ;
REQUIRE ( v1 = = nullptr ) ;
REQUIRE ( v2 = = uptr . get ( ) ) ;
REQUIRE ( v2 = = nullptr ) ;
REQUIRE ( v3 = = rptr ) ;
REQUIRE ( v3 = = nullptr ) ;
REQUIRE ( v4 = = vptr ) ;
REQUIRE ( v4 = = nullptr ) ;
} ( ) ) ;
}
SECTION ( " ptr " ) {
sol : : state lua ;
lua . open_libraries ( ) ;
lua [ " v1 " ] = sptr ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
lua [ " v3 " ] = rptr ;
lua [ " v4 " ] = vptr ;
lua [ " f " ] = & nil_test : : f ;
lua [ " g " ] = & nil_test : : g ;
lua [ " h " ] = & nil_test : : h ;
REQUIRE_NOTHROW ( [ & ] ( ) {
2017-08-22 03:25:43 +08:00
lua . safe_script ( " f(v1) " ) ;
lua . safe_script ( " f(v2) " ) ;
lua . safe_script ( " f(v3) " ) ;
lua . safe_script ( " f(v4) " ) ;
lua . safe_script ( " assert(v1 == nil) " ) ;
lua . safe_script ( " assert(v2 == nil) " ) ;
lua . safe_script ( " assert(v3 == nil) " ) ;
lua . safe_script ( " assert(v4 == nil) " ) ;
2017-07-01 06:18:25 +08:00
} ( ) ) ;
}
SECTION ( " throw unique argument " ) {
sol : : state lua ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
lua [ " g " ] = & nil_test : : g ;
2017-08-11 15:24:17 +08:00
auto result = lua . safe_script ( " g(v2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-07-01 06:18:25 +08:00
}
SECTION ( " throw shared argument " ) {
sol : : state lua ;
lua [ " v1 " ] = sptr ;
lua [ " h " ] = & nil_test : : h ;
2017-08-11 15:24:17 +08:00
auto result = lua . safe_script ( " h(v1) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-07-01 06:18:25 +08:00
}
SECTION ( " throw ref " ) {
2017-09-01 08:47:09 +08:00
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v1 " ] = sptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v1 " ] ;
bool isp = o . is < nil_test & > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v2 " ] ;
bool isp = o . is < nil_test & > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v3 " ] = rptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v3 " ] ;
bool isp = o . is < nil_test & > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v4 " ] = vptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v4 " ] ;
bool isp = o . is < nil_test & > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
2017-07-01 06:18:25 +08:00
}
SECTION ( " throw unique " ) {
2017-09-01 08:47:09 +08:00
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v1 " ] = sptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v1 " ] ;
bool isp = o . is < std : : unique_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v2 " ] ;
bool isp = o . is < std : : unique_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v3 " ] = rptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v3 " ] ;
bool isp = o . is < std : : unique_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
} ;
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v4 " ] = vptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v4 " ] ;
bool isp = o . is < std : : unique_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
} ;
2017-07-01 06:18:25 +08:00
}
SECTION ( " throw shared " ) {
2017-09-01 08:47:09 +08:00
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v1 " ] = sptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v1 " ] ;
bool isp = o . is < std : : shared_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v2 " ] = std : : unique_ptr < nil_test > ( ) ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v2 " ] ;
bool isp = o . is < std : : shared_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v3 " ] = rptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v3 " ] ;
bool isp = o . is < std : : shared_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
{
2017-07-01 06:18:25 +08:00
sol : : state lua ;
lua [ " v4 " ] = vptr ;
2017-09-01 08:47:09 +08:00
sol : : object o = lua [ " v4 " ] ;
bool isp = o . is < std : : shared_ptr < nil_test > > ( ) ;
REQUIRE_FALSE ( isp ) ;
}
2017-07-01 06:18:25 +08:00
}
}
2017-08-06 07:20:28 +08:00
TEST_CASE ( " functions/unique_usertype overloading " , " make sure overloading can work with ptr vs. specifically asking for a unique_usertype " ) {
2017-09-17 02:18:45 +08:00
struct test {
2017-06-15 13:23:51 +08:00
int special_value = 17 ;
2019-08-28 06:36:45 +08:00
test ( ) : special_value ( 17 ) {
2017-09-17 02:18:45 +08:00
}
2019-08-28 06:36:45 +08:00
test ( int special_value ) : special_value ( special_value ) {
2017-09-17 02:18:45 +08:00
}
2017-06-15 13:23:51 +08:00
} ;
2019-08-28 06:36:45 +08:00
auto print_up_test = [ ] ( std : : unique_ptr < test > & x ) { REQUIRE ( x - > special_value = = 21 ) ; } ;
auto print_up_2_test = [ ] ( int , std : : unique_ptr < test > & x ) { REQUIRE ( x - > special_value = = 21 ) ; } ;
auto print_sp_test = [ ] ( std : : shared_ptr < test > & x ) { REQUIRE ( x - > special_value = = 44 ) ; } ;
auto print_ptr_test = [ ] ( test * x ) { REQUIRE ( x - > special_value = = 17 ) ; } ;
2017-06-15 13:23:51 +08:00
auto print_ref_test = [ ] ( test & x ) {
2019-08-28 06:36:45 +08:00
bool is_any = x . special_value = = 17 | | x . special_value = = 21 | | x . special_value = = 44 ;
2017-06-15 13:23:51 +08:00
REQUIRE ( is_any ) ;
} ;
using f_t = void ( test & ) ;
f_t * fptr = print_ref_test ;
2017-09-17 02:18:45 +08:00
2017-06-15 13:23:51 +08:00
std : : unique_ptr < test > ut = std : : make_unique < test > ( 17 ) ;
SECTION ( " working " ) {
sol : : state lua ;
2017-06-14 04:34:18 +08:00
2017-06-15 13:23:51 +08:00
lua . set_function ( " f " , print_up_test ) ;
2017-09-17 02:18:45 +08:00
lua . set_function ( " g " , sol : : overload ( std : : move ( print_sp_test ) , print_up_test , std : : ref ( print_ptr_test ) ) ) ;
2017-06-15 13:23:51 +08:00
lua . set_function ( " h " , std : : ref ( fptr ) ) ;
2017-06-26 22:10:47 +08:00
lua . set_function ( " i " , std : : move ( print_up_2_test ) ) ;
2017-06-15 13:23:51 +08:00
lua [ " v1 " ] = std : : make_unique < test > ( 21 ) ;
lua [ " v2 " ] = std : : make_shared < test > ( 44 ) ;
lua [ " v3 " ] = test ( 17 ) ;
lua [ " v4 " ] = ut . get ( ) ;
2017-12-07 21:24:50 +08:00
{
auto result = lua . safe_script ( " f(v1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " g(v1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " g(v2) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " g(v3) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " g(v4) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " h(v1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " h(v2) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " h(v3) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " h(v4) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
{
auto result = lua . safe_script ( " i(20, v1) " , sol : : script_pass_on_error ) ;
REQUIRE ( result . valid ( ) ) ;
}
2017-06-15 13:23:51 +08:00
} ;
// LuaJIT segfaults hard on some Linux machines
// and it breaks all the tests...
SECTION ( " throws-value " ) {
sol : : state lua ;
lua . set_function ( " f " , print_up_test ) ;
lua [ " v3 " ] = test ( 17 ) ;
2017-08-11 15:24:17 +08:00
auto result = lua . safe_script ( " f(v3) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-06-15 13:23:51 +08:00
} ;
SECTION ( " throws-shared_ptr " ) {
sol : : state lua ;
lua . set_function ( " f " , print_up_test ) ;
lua [ " v2 " ] = std : : make_shared < test > ( 44 ) ;
2017-06-14 04:34:18 +08:00
2017-08-11 15:24:17 +08:00
auto result = lua . safe_script ( " f(v2) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-06-15 13:23:51 +08:00
} ;
SECTION ( " throws-ptr " ) {
sol : : state lua ;
lua . set_function ( " f " , print_up_test ) ;
lua [ " v4 " ] = ut . get ( ) ;
2017-08-11 15:24:17 +08:00
auto result = lua . safe_script ( " f(v4) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
2017-06-15 13:23:51 +08:00
} ;
2017-06-14 04:34:18 +08:00
}
2017-06-15 01:24:13 +08:00
2018-03-22 22:59:37 +08:00
TEST_CASE ( " functions/lua style default arguments " , " allow default arguments using sol::reference and sol::object " ) {
auto def_f1 = [ ] ( sol : : object defaulted ) - > int {
bool inactive = defaulted = = sol : : lua_nil ; // inactive by default
if ( inactive ) {
return 20 ;
}
return 10 ;
2018-03-04 02:42:13 +08:00
} ;
2018-03-22 22:59:37 +08:00
auto def_f2 = [ ] ( sol : : reference defaulted ) - > int {
bool inactive = defaulted = = sol : : lua_nil ; // inactive by default
if ( inactive ) {
return 20 ;
}
return 10 ;
2018-03-04 02:42:13 +08:00
} ;
2018-03-22 22:59:37 +08:00
auto def_f3 = [ ] ( sol : : stack_reference defaulted ) - > int {
bool inactive = defaulted = = sol : : lua_nil ; // inactive by default
if ( inactive ) {
return 20 ;
}
return 10 ;
} ;
sol : : state lua ;
lua . set_function ( " f1 " , def_f1 ) ;
lua . set_function ( " f2 " , def_f2 ) ;
lua . set_function ( " f3 " , def_f3 ) ;
auto result = lua . safe_script ( R " (
v1d , v1nd = f1 ( ) , f1 ( 1 )
v2d , v2nd = f2 ( ) , f2 ( 1 )
v3d , v3nd = f3 ( ) , f3 ( 1 )
2019-08-28 06:36:45 +08:00
) " ,
sol : : script_pass_on_error ) ;
2018-03-22 22:59:37 +08:00
REQUIRE ( result . valid ( ) ) ;
int v1d = lua [ " v1d " ] ;
int v1nd = lua [ " v1nd " ] ;
int v2d = lua [ " v2d " ] ;
int v2nd = lua [ " v2nd " ] ;
int v3d = lua [ " v3d " ] ;
int v3nd = lua [ " v3nd " ] ;
REQUIRE ( 20 = = v1d ) ;
REQUIRE ( 20 = = v2d ) ;
REQUIRE ( 20 = = v3d ) ;
REQUIRE ( 10 = = v1nd ) ;
REQUIRE ( 10 = = v2nd ) ;
2018-03-04 02:42:13 +08:00
REQUIRE ( 10 = = v3nd ) ;
}