Add more comprehensive unregistration tests

- Make sure multiple states don't interfere with each other's keys
- Make sure re-registration of the same type does not cause too many problems
- Make sure the variadics test is present
- Make sure the storage keys are cleared out properly
This commit is contained in:
ThePhD 2020-12-30 09:36:23 -05:00
parent f7d99b05a5
commit 8f7d4dbb4c
No known key found for this signature in database
GPG Key ID: 1509DB1C0F702BFA
7 changed files with 145 additions and 16 deletions

View File

@ -444,6 +444,7 @@ namespace sol { namespace u_detail {
storage.clear(); storage.clear();
string_keys.clear(); string_keys.clear();
auxiliary_keys.clear(); auxiliary_keys.clear();
string_keys_storage.clear();
} }
template <bool is_new_index, typename Base> template <bool is_new_index, typename Base>

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-12-30 02:56:57.400161 UTC // Generated 2020-12-30 14:35:06.977732 UTC
// This header was generated with sol v3.2.3 (revision b9115623) // This header was generated with sol v3.2.3 (revision f7d99b05)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_CONFIG_HPP #ifndef SOL_SINGLE_CONFIG_HPP

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-12-30 02:56:57.318161 UTC // Generated 2020-12-30 14:35:06.965732 UTC
// This header was generated with sol v3.2.3 (revision b9115623) // This header was generated with sol v3.2.3 (revision f7d99b05)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP #ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP

View File

@ -20,8 +20,8 @@
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// This file was generated with a script. // This file was generated with a script.
// Generated 2020-12-30 02:56:53.623397 UTC // Generated 2020-12-30 14:35:06.134327 UTC
// This header was generated with sol v3.2.3 (revision b9115623) // This header was generated with sol v3.2.3 (revision f7d99b05)
// https://github.com/ThePhD/sol2 // https://github.com/ThePhD/sol2
#ifndef SOL_SINGLE_INCLUDE_HPP #ifndef SOL_SINGLE_INCLUDE_HPP
@ -22414,6 +22414,7 @@ namespace sol { namespace u_detail {
storage.clear(); storage.clear();
string_keys.clear(); string_keys.clear();
auxiliary_keys.clear(); auxiliary_keys.clear();
string_keys_storage.clear();
} }
template <bool is_new_index, typename Base> template <bool is_new_index, typename Base>

View File

@ -39,4 +39,4 @@ unsigned int regression_1096() {
} }
} }
return accumulated_errors; return accumulated_errors;
} }

View File

@ -25,17 +25,27 @@
#include <catch.hpp> #include <catch.hpp>
struct unregister_me { inline namespace sol2_tests_usertypes_unregister {
double b = 5.5; struct unregister_me {
std::string f_val = "registered"; double b = 5.5;
std::string f_val = "registered";
unregister_me() { unregister_me() {
} }
std::string f() { std::string f() {
return f_val; return f_val;
} }
}; };
struct goddamnit {};
struct state_pointer_and_registration {
sol::state* lua_ptr;
bool* registered_ptr;
};
}
TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but that it becomes completely unregistered") { TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but that it becomes completely unregistered") {
const sol::string_view line1 = "assert(u:f() == 'registered')"; const sol::string_view line1 = "assert(u:f() == 'registered')";
@ -145,3 +155,88 @@ TEST_CASE("usertypes/unregister", "make sure that a class can still be bound but
REQUIRE(u.f() == "registered"); REQUIRE(u.f() == "registered");
} }
} }
TEST_CASE("usertypes/unregister multiple states", "guarantee unregistration can happen from multiple states without interfering with the originals") {
sol::state lua0;
bool lua0_registered = false;
lua0.open_libraries(sol::lib::base);
lua0.new_usertype<goddamnit>("goddamnit", "a", sol::property([i=0](){ return i; }));
sol::state lua1;
bool lua1_registered = false;
lua1.open_libraries(sol::lib::base);
lua1.new_usertype<goddamnit>("goddamnit", "a", sol::property([i=1](){ return i; }));
sol::state lua2;
bool lua2_registered = false;
lua2.open_libraries(sol::lib::base);
lua2.new_usertype<goddamnit>("goddamnit", "a", sol::property([i=2](){ return i; }));
state_pointer_and_registration states[] = { { &lua0, &lua0_registered }, { &lua1, &lua1_registered }, { &lua2, &lua2_registered } };
const std::size_t number_of_states = std::size(states);
auto prove = [](sol::state& lua, const bool& is_registered, std::size_t state_index) {
std::string code = "val = gdi.a\nprint(val)";
if (is_registered) {
sol::optional<sol::error> maybe_error = lua.safe_script(code, sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error.has_value());
sol::optional<std::size_t> maybe_val = lua["val"];
REQUIRE(maybe_val.has_value());
const std::size_t& val = *maybe_val;
REQUIRE(val == state_index);
}
else {
sol::optional<sol::error> maybe_error = lua.safe_script(code, sol::script_pass_on_error);
REQUIRE(maybe_error.has_value());
const sol::error& error = *maybe_error;
std::string err = error.what();
REQUIRE((err.find("attempt to index") != std::string::npos) || (err.find("gdi") != std::string::npos));
}
};
for (std::size_t i = 0; i < number_of_states; ++i) {
state_pointer_and_registration& repr = states[i];
sol::state& lua = *repr.lua_ptr;
bool& is_registered = *repr.registered_ptr;
lua["gdi"] = goddamnit{};
is_registered = true;
prove(lua, is_registered, i);
}
{
sol::metatable goddamnit_usertype0 = lua0["goddamnit"];
goddamnit_usertype0.unregister();
lua0_registered = false;
}
for (std::size_t i = 0; i < number_of_states; ++i) {
state_pointer_and_registration& repr = states[i];
sol::state& lua = *repr.lua_ptr;
bool& is_registered = *repr.registered_ptr;
prove(lua, is_registered, i);
}
{
sol::usertype<goddamnit> goddamnit_usertype1 = lua1["goddamnit"];
goddamnit_usertype1.unregister();
lua1_registered = false;
}
for (std::size_t i = 0; i < number_of_states; ++i) {
state_pointer_and_registration& repr = states[i];
sol::state& lua = *repr.lua_ptr;
bool& is_registered = *repr.registered_ptr;
prove(lua, is_registered, i);
}
{
lua0.new_usertype<goddamnit>("goddamnit", "a", sol::property([i=0](){ return i; }));
lua0_registered = true;
}
for (std::size_t i = 0; i < number_of_states; ++i) {
state_pointer_and_registration& repr = states[i];
sol::state& lua = *repr.lua_ptr;
bool& is_registered = *repr.registered_ptr;
prove(lua, is_registered, i);
}
}

View File

@ -317,3 +317,35 @@ local obj3 = foo3.new(0, 1, 2)
sol::script_pass_on_error); sol::script_pass_on_error);
REQUIRE_FALSE(maybe_err.has_value()); REQUIRE_FALSE(maybe_err.has_value());
} }
TEST_CASE("variadics/overloads with fallbacks",
"Test that 'fuzzy' types like optional and variadic_args can coexist and have optional numbers of arguments passed to them") {
sol::state lua;
lua.open_libraries(sol::lib::base);
auto test = lua[u8"test"].get_or_create<sol::table>();
auto derp = test[u8"derp"].get_or_create<sol::table>();
derp[u8"herp"]
= sol::overload([](sol::this_state, const std::string_view&, const std::string_view&, const std::string_view&, sol::optional<uint32_t>) { return 1; },
[](const std::string_view&, const std::string_view&, sol::function, sol::optional<uint32_t>) { return 2; },
[](sol::this_state, sol::variadic_args) { return 3; });
const std::string_view code = R"(
assert(test.derp.herp('str1', 'str2', 'str3') == 1);
assert(test.derp.herp('str1', 'str2', 'str3', 42) == 1);
assert(test.derp.herp('str1', 'str2', 'str3', nil) == 1);
assert(test.derp.herp('str1', 'str2', function(r) end) == 2);
assert(test.derp.herp('str1', 'str2', function(r) end, 42) == 2);
assert(test.derp.herp('str1', 'str2', function(r) end, nil) == 2);
assert(test.derp.herp('str1', 'str2', 'str3', {}) == 3);
assert(test.derp.herp('str1', 'str2', function(r) end, {}) == 3);
assert(test.derp.herp(1, 2, 3, 4, 5, 6, 7) == 3);
assert(test.derp.herp('str1', 'str2', 'str3', 'str4') == 3);
)";
sol::optional<sol::error> maybe_error = lua.safe_script(code, sol::script_pass_on_error);
REQUIRE_FALSE(maybe_error.has_value());
}