summaryrefslogtreecommitdiff
path: root/tests/core
diff options
context:
space:
mode:
authorYuri Sizov <yuris@humnom.net>2022-08-08 15:18:26 +0300
committerYuri Sizov <yuris@humnom.net>2022-08-08 16:36:01 +0300
commit1362bc22bd636190dfaf6876fbec86e2cd7a34b7 (patch)
tree5d7100b67adca69e3cf5b451839f051499395404 /tests/core
parentbeceba85da9d53dad33c1a0d3f59c24e966b1c35 (diff)
Add tests for empty/unnamed arguments to ClassDB, Variant, GDScript
Diffstat (limited to 'tests/core')
-rw-r--r--tests/core/object/test_class_db.h82
-rw-r--r--tests/core/variant/test_variant.h62
2 files changed, 101 insertions, 43 deletions
diff --git a/tests/core/object/test_class_db.h b/tests/core/object/test_class_db.h
index fc329ba0eb..208923edb9 100644
--- a/tests/core/object/test_class_db.h
+++ b/tests/core/object/test_class_db.h
@@ -71,6 +71,7 @@ struct ArgumentData {
String name;
bool has_defval = false;
Variant defval;
+ int position;
};
struct MethodData {
@@ -371,6 +372,39 @@ void validate_property(const Context &p_context, const ExposedClass &p_class, co
}
}
+void validate_argument(const Context &p_context, const ExposedClass &p_class, const String &p_owner_name, const String &p_owner_type, const ArgumentData &p_arg) {
+ TEST_COND((p_arg.name.is_empty() || p_arg.name.begins_with("_unnamed_arg")),
+ vformat("Unnamed argument in position %d of %s '%s.%s'.", p_arg.position, p_owner_type, p_class.name, p_owner_name));
+
+ const ExposedClass *arg_class = p_context.find_exposed_class(p_arg.type);
+ if (arg_class) {
+ TEST_COND(arg_class->is_singleton,
+ vformat("Argument type is a singleton: '%s' of %s '%s.%s'.", p_arg.name, p_owner_type, p_class.name, p_owner_name));
+
+ if (p_class.api_type == ClassDB::API_CORE) {
+ TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
+ vformat("Argument '%s' of %s '%s.%s' has type '%s' from the editor API. Core API cannot have dependencies on the editor API.",
+ p_arg.name, p_owner_type, p_class.name, p_owner_name, arg_class->name));
+ }
+ } else {
+ // Look for types that don't inherit Object.
+ TEST_FAIL_COND(!p_context.has_type(p_arg.type),
+ vformat("Argument type '%s' not found: '%s' of %s '%s.%s'.", p_arg.type.name, p_arg.name, p_owner_type, p_class.name, p_owner_name));
+ }
+
+ if (p_arg.has_defval) {
+ String type_error_msg;
+ bool arg_defval_assignable_to_type = arg_default_value_is_assignable_to_type(p_context, p_arg.defval, p_arg.type, &type_error_msg);
+
+ String err_msg = vformat("Invalid default value for parameter '%s' of %s '%s.%s'.", p_arg.name, p_owner_type, p_class.name, p_owner_name);
+ if (!type_error_msg.is_empty()) {
+ err_msg += " " + type_error_msg;
+ }
+
+ TEST_COND(!arg_defval_assignable_to_type, err_msg.utf8().get_data());
+ }
+}
+
void validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) {
if (p_method.return_type.name != StringName()) {
const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
@@ -392,54 +426,14 @@ void validate_method(const Context &p_context, const ExposedClass &p_class, cons
for (const ArgumentData &F : p_method.arguments) {
const ArgumentData &arg = F;
-
- const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
- if (arg_class) {
- TEST_COND(arg_class->is_singleton,
- "Argument type is a singleton: '", arg.name, "' of method '", p_class.name, ".", p_method.name, "'.");
-
- if (p_class.api_type == ClassDB::API_CORE) {
- TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
- "Argument '", arg.name, "' of method '", p_class.name, ".", p_method.name, "' has type '",
- arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
- }
- } else {
- // Look for types that don't inherit Object
- TEST_FAIL_COND(!p_context.has_type(arg.type),
- "Argument type '", arg.type.name, "' not found: '", arg.name, "' of method", p_class.name, ".", p_method.name, "'.");
- }
-
- if (arg.has_defval) {
- String type_error_msg;
- bool arg_defval_assignable_to_type = arg_default_value_is_assignable_to_type(p_context, arg.defval, arg.type, &type_error_msg);
- String err_msg = vformat("Invalid default value for parameter '%s' of method '%s.%s'.", arg.name, p_class.name, p_method.name);
- if (!type_error_msg.is_empty()) {
- err_msg += " " + type_error_msg;
- }
- TEST_COND(!arg_defval_assignable_to_type, err_msg.utf8().get_data());
- }
+ validate_argument(p_context, p_class, p_method.name, "method", arg);
}
}
void validate_signal(const Context &p_context, const ExposedClass &p_class, const SignalData &p_signal) {
for (const ArgumentData &F : p_signal.arguments) {
const ArgumentData &arg = F;
-
- const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
- if (arg_class) {
- TEST_COND(arg_class->is_singleton,
- "Argument class is a singleton: '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "'.");
-
- if (p_class.api_type == ClassDB::API_CORE) {
- TEST_COND(arg_class->api_type == ClassDB::API_EDITOR,
- "Argument '", arg.name, "' of signal '", p_class.name, ".", p_signal.name, "' has type '",
- arg_class->name, "' from the editor API. Core API cannot have dependencies on the editor API.");
- }
- } else {
- // Look for types that don't inherit Object
- TEST_FAIL_COND(!p_context.has_type(arg.type),
- "Argument type '", arg.type.name, "' not found: '", arg.name, "' of signal", p_class.name, ".", p_signal.name, "'.");
- }
+ validate_argument(p_context, p_class, p_signal.name, "signal", arg);
}
}
@@ -625,6 +619,7 @@ void add_exposed_classes(Context &r_context) {
ArgumentData arg;
arg.name = orig_arg_name;
+ arg.position = i;
if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
arg.type.name = arg_info.class_name;
@@ -693,6 +688,7 @@ void add_exposed_classes(Context &r_context) {
ArgumentData arg;
arg.name = orig_arg_name;
+ arg.position = i;
if (arg_info.type == Variant::INT && arg_info.usage & (PROPERTY_USAGE_CLASS_IS_ENUM | PROPERTY_USAGE_CLASS_IS_BITFIELD)) {
arg.type.name = arg_info.class_name;
@@ -841,7 +837,7 @@ TEST_SUITE("[ClassDB]") {
add_builtin_types(context);
add_global_enums(context);
- SUBCASE("[ClassDB] Find exposed class") {
+ SUBCASE("[ClassDB] Validate exposed classes") {
const ExposedClass *object_class = context.find_exposed_class(context.names_cache.object_class);
TEST_FAIL_COND(!object_class, "Object class not found.");
TEST_FAIL_COND(object_class->base != StringName(),
diff --git a/tests/core/variant/test_variant.h b/tests/core/variant/test_variant.h
index 916686d7c1..d6799928b4 100644
--- a/tests/core/variant/test_variant.h
+++ b/tests/core/variant/test_variant.h
@@ -719,6 +719,7 @@ TEST_CASE("[Variant] Assignment To Color from Bool,Int,Float,String,Vec2,Vec2i,V
vec3i_v = col_v;
CHECK(vec3i_v.get_type() == Variant::COLOR);
}
+
TEST_CASE("[Variant] Writer and parser array") {
Array a = build_array(1, String("hello"), build_array(Variant()));
String a_str;
@@ -911,6 +912,67 @@ TEST_CASE("[Variant] Nested dictionary comparison") {
CHECK_FALSE(v_d1 == v_d_other_val);
}
+struct ArgumentData {
+ Variant::Type type;
+ String name;
+ bool has_defval = false;
+ Variant defval;
+ int position;
+};
+
+struct MethodData {
+ StringName name;
+ Variant::Type return_type;
+ List<ArgumentData> arguments;
+ bool is_virtual = false;
+ bool is_vararg = false;
+};
+
+TEST_CASE("[Variant] Utility functions") {
+ List<MethodData> functions;
+
+ List<StringName> function_names;
+ Variant::get_utility_function_list(&function_names);
+ function_names.sort_custom<StringName::AlphCompare>();
+
+ for (const StringName &E : function_names) {
+ MethodData md;
+ md.name = E;
+
+ // Utility function's return type.
+ if (Variant::has_utility_function_return_value(E)) {
+ md.return_type = Variant::get_utility_function_return_type(E);
+ }
+
+ // Utility function's arguments.
+ if (Variant::is_utility_function_vararg(E)) {
+ md.is_vararg = true;
+ } else {
+ for (int i = 0; i < Variant::get_utility_function_argument_count(E); i++) {
+ ArgumentData arg;
+ arg.type = Variant::get_utility_function_argument_type(E, i);
+ arg.name = Variant::get_utility_function_argument_name(E, i);
+ arg.position = i;
+
+ md.arguments.push_back(arg);
+ }
+ }
+
+ functions.push_back(md);
+ }
+
+ SUBCASE("[Variant] Validate utility functions") {
+ for (const MethodData &E : functions) {
+ for (const ArgumentData &F : E.arguments) {
+ const ArgumentData &arg = F;
+
+ TEST_COND((arg.name.is_empty() || arg.name.begins_with("_unnamed_arg")),
+ vformat("Unnamed argument in position %d of function '%s'.", arg.position, E.name));
+ }
+ }
+ }
+}
+
} // namespace TestVariant
#endif // TEST_VARIANT_H