2017-07-10 00:00:57 +08:00
# define SOL_CHECK_ARGUMENTS
# include <catch.hpp>
# include <sol.hpp>
2017-08-11 15:24:17 +08:00
# include <mutex>
2017-08-06 07:20:28 +08:00
# include <thread>
2017-07-10 00:00:57 +08:00
# ifdef SOL_CXX17_FEATURES
# include <string_view>
# include <variant>
# endif
2017-08-11 15:24:17 +08:00
std : : mutex basic_init_require_mutex ;
2017-08-06 07:20:28 +08:00
void basic_initialization_and_lib_open ( ) {
2017-08-11 15:24:17 +08:00
2017-08-06 07:20:28 +08:00
sol : : state lua ;
try {
lua . open_libraries ( ) ;
lua [ " a " ] = 24 ;
int a = lua [ " a " ] ;
2017-08-11 15:24:17 +08:00
{
std : : lock_guard < std : : mutex > lg ( basic_init_require_mutex ) ;
REQUIRE ( a = = 24 ) ;
}
2017-08-06 07:20:28 +08:00
}
catch ( const sol : : error & e ) {
2017-08-11 15:24:17 +08:00
std : : lock_guard < std : : mutex > lg ( basic_init_require_mutex ) ;
2017-08-06 07:20:28 +08:00
INFO ( e . what ( ) ) ;
REQUIRE ( false ) ;
}
catch ( . . . ) {
2017-08-11 15:24:17 +08:00
std : : lock_guard < std : : mutex > lg ( basic_init_require_mutex ) ;
2017-08-06 07:20:28 +08:00
REQUIRE ( false ) ;
}
}
2017-07-10 00:00:57 +08:00
TEST_CASE ( " utility/variant " , " test that variant can be round-tripped " ) {
# ifdef SOL_CXX17_FEATURES
SECTION ( " okay " ) {
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . set_function ( " f " , [ ] ( int v ) {
return v = = 2 ;
} ) ;
lua . set_function ( " g " , [ ] ( std : : variant < float , int , std : : string > vv ) {
int v = std : : get < int > ( vv ) ;
return v = = 2 ;
} ) ;
lua [ " v " ] = std : : variant < float , int , std : : string > ( 2 ) ;
REQUIRE_NOTHROW ( [ & ] ( ) {
lua . script ( " assert(f(v)) " ) ;
lua . script ( " assert(g(v)) " ) ;
} ( ) ) ;
}
SECTION ( " throws " ) {
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . set_function ( " f " , [ ] ( int v ) {
return v = = 2 ;
} ) ;
lua . set_function ( " g " , [ ] ( std : : variant < float , int , std : : string > vv ) {
int v = std : : get < int > ( vv ) ;
return v = = 2 ;
} ) ;
lua [ " v " ] = std : : variant < float , int , std : : string > ( std : : string ( " bark " ) ) ;
2017-08-11 15:24:17 +08:00
{
auto result = lua . safe_script ( " assert(f(v)) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
} ;
{
auto result = lua . safe_script ( " assert(g(v)) " , sol : : script_pass_on_error ) ;
REQUIRE_FALSE ( result . valid ( ) ) ;
} ;
2017-07-10 00:00:57 +08:00
}
# else
REQUIRE ( true ) ;
# endif // C++17
}
TEST_CASE ( " utility/string_view " , " test that string_view can be taken as an argument " ) {
# ifdef SOL_CXX17_FEATURES
sol : : state lua ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . set_function ( " f " , [ ] ( std : : string_view v ) {
return v = = " bark! " ;
} ) ;
lua [ " v " ] = " bark! " ;
REQUIRE_NOTHROW ( [ & ] ( ) {
lua . script ( " assert(f(v)) " ) ;
} ( ) ) ;
# else
REQUIRE ( true ) ;
# endif // C++17
2017-08-06 07:20:28 +08:00
}
TEST_CASE ( " utility/thread " , " fire up lots of threads at the same time to make sure the initialization changes do not cause horrible crashing data races " ) {
REQUIRE_NOTHROW ( [ ] ( ) {
std : : thread thrds [ 16 ] ;
for ( int i = 0 ; i < 16 ; i + + ) {
thrds [ i ] = std : : thread ( & basic_initialization_and_lib_open ) ;
}
for ( int i = 0 ; i < 16 ; i + + ) {
thrds [ i ] . join ( ) ;
}
} ( ) ) ;
}
TEST_CASE ( " utility/this_state " , " Ensure this_state argument can be gotten anywhere in the function. " ) {
struct bark {
int with_state ( sol : : this_state l , int a , int b ) {
lua_State * L = l ;
int c = lua_gettop ( L ) ;
return a + b + ( c - c ) ;
}
static int with_state_2 ( int a , sol : : this_state l , int b ) {
INFO ( " inside with_state_2 " ) ;
lua_State * L = l ;
INFO ( " L is " < < ( void * ) L ) ;
int c = lua_gettop ( L ) ;
return a * b + ( c - c ) ;
}
} ;
sol : : state lua ;
INFO ( " created lua state " ) ;
lua . open_libraries ( sol : : lib : : base ) ;
lua . new_usertype < bark > ( " bark " ,
" with_state " , & bark : : with_state
) ;
INFO ( " setting b and with_state_2 " ) ;
bark b ;
lua . set ( " b " , & b ) ;
lua . set ( " with_state_2 " , bark : : with_state_2 ) ;
INFO ( " finished setting " ) ;
INFO ( " getting fx " ) ;
sol : : function fx = lua [ " with_state_2 " ] ;
INFO ( " calling fx " ) ;
int a = fx ( 25 , 25 ) ;
INFO ( " finished setting fx " ) ;
INFO ( " calling a script " ) ;
lua . script ( " a = with_state_2(25, 25) " ) ;
INFO ( " calling c script " ) ;
lua . script ( " c = b:with_state(25, 25) " ) ;
INFO ( " getting a " ) ;
int la = lua [ " a " ] ;
INFO ( " getting b " ) ;
int lc = lua [ " c " ] ;
REQUIRE ( lc = = 50 ) ;
REQUIRE ( a = = 625 ) ;
REQUIRE ( la = = 625 ) ;
}