summaryrefslogtreecommitdiff
path: root/tests/scene/test_theme.h
diff options
context:
space:
mode:
authorHaoyu Qiu <timothyqiu32@gmail.com>2022-04-26 18:21:34 +0800
committerHaoyu Qiu <timothyqiu32@gmail.com>2022-04-26 19:54:43 +0800
commitd8c04cda3a77b281f3785074a76ff3d3a2cb7cde (patch)
treeda00a5d3f36b5c785b5492aada175a33bfd795b0 /tests/scene/test_theme.h
parenta8abdc9372cb748aaa3f6021cf0c3719a3a64033 (diff)
Validate theme type/item names
Diffstat (limited to 'tests/scene/test_theme.h')
-rw-r--r--tests/scene/test_theme.h257
1 files changed, 257 insertions, 0 deletions
diff --git a/tests/scene/test_theme.h b/tests/scene/test_theme.h
new file mode 100644
index 0000000000..fedffc8449
--- /dev/null
+++ b/tests/scene/test_theme.h
@@ -0,0 +1,257 @@
+/*************************************************************************/
+/* test_theme.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#ifndef TEST_THEME_H
+#define TEST_THEME_H
+
+#include "scene/resources/theme.h"
+#include "tests/test_tools.h"
+
+#include "thirdparty/doctest/doctest.h"
+
+namespace TestTheme {
+
+class Fixture {
+public:
+ struct DataEntry {
+ Theme::DataType type;
+ Variant value;
+ } const valid_data[Theme::DATA_TYPE_MAX] = {
+ { Theme::DATA_TYPE_COLOR, Color() },
+ { Theme::DATA_TYPE_CONSTANT, 42 },
+ { Theme::DATA_TYPE_FONT, Ref<Font>(memnew(Font)) },
+ { Theme::DATA_TYPE_FONT_SIZE, 42 },
+ { Theme::DATA_TYPE_ICON, Ref<Texture>(memnew(ImageTexture)) },
+ { Theme::DATA_TYPE_STYLEBOX, Ref<StyleBox>(memnew(StyleBoxFlat)) },
+ };
+
+ const StringName valid_item_name = "valid_item_name";
+ const StringName valid_type_name = "ValidTypeName";
+};
+
+TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme type names") {
+ StringName names[] = {
+ "", // Empty name.
+ "CapitalizedName",
+ "snake_cased_name",
+ "42",
+ "_Underscore_",
+ };
+
+ SUBCASE("add_type") {
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->add_type(name);
+ CHECK_FALSE(ed.has_error);
+ }
+ }
+
+ SUBCASE("set_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_theme_item(entry.type, valid_item_name, name, entry.value);
+ CHECK_FALSE(ed.has_error);
+ }
+ }
+ }
+
+ SUBCASE("add_theme_item_type") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->add_theme_item_type(entry.type, name);
+ CHECK_FALSE(ed.has_error);
+ }
+ }
+ }
+
+ SUBCASE("set_type_variation") {
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_type_variation(valid_type_name, name);
+ CHECK(ed.has_error == (name == StringName()));
+ }
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_type_variation(name, valid_type_name);
+ CHECK(ed.has_error == (name == StringName()));
+ }
+ }
+}
+
+TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme type names") {
+ StringName names[] = {
+ "With/Slash",
+ "With Space",
+ "With@various$symbols!",
+ String::utf8("contains_汉字"),
+ };
+
+ SUBCASE("add_type") {
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->add_type(name);
+ CHECK(ed.has_error);
+ }
+ }
+
+ SUBCASE("set_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_theme_item(entry.type, valid_item_name, name, entry.value);
+ CHECK(ed.has_error);
+ }
+ }
+ }
+
+ SUBCASE("add_theme_item_type") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->add_theme_item_type(entry.type, name);
+ CHECK(ed.has_error);
+ }
+ }
+ }
+
+ SUBCASE("set_type_variation") {
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_type_variation(valid_type_name, name);
+ CHECK(ed.has_error);
+ }
+ for (const StringName &name : names) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_type_variation(name, valid_type_name);
+ CHECK(ed.has_error);
+ }
+ }
+}
+
+TEST_CASE_FIXTURE(Fixture, "[Theme] Good theme item names") {
+ StringName names[] = {
+ "CapitalizedName",
+ "snake_cased_name",
+ "42",
+ "_Underscore_",
+ };
+
+ SUBCASE("set_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_theme_item(entry.type, name, valid_type_name, entry.value);
+ CHECK_FALSE(ed.has_error);
+ CHECK(theme->has_theme_item(entry.type, name, valid_type_name));
+ }
+ }
+ }
+
+ SUBCASE("rename_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+ theme->set_theme_item(entry.type, valid_item_name, valid_type_name, entry.value);
+
+ ErrorDetector ed;
+ theme->rename_theme_item(entry.type, valid_item_name, name, valid_type_name);
+ CHECK_FALSE(ed.has_error);
+ CHECK_FALSE(theme->has_theme_item(entry.type, valid_item_name, valid_type_name));
+ CHECK(theme->has_theme_item(entry.type, name, valid_type_name));
+ }
+ }
+ }
+}
+
+TEST_CASE_FIXTURE(Fixture, "[Theme] Bad theme item names") {
+ StringName names[] = {
+ "", // Empty name.
+ "With/Slash",
+ "With Space",
+ "With@various$symbols!",
+ String::utf8("contains_汉字"),
+ };
+
+ SUBCASE("set_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+
+ ErrorDetector ed;
+ theme->set_theme_item(entry.type, name, valid_type_name, entry.value);
+ CHECK(ed.has_error);
+ CHECK_FALSE(theme->has_theme_item(entry.type, name, valid_type_name));
+ }
+ }
+ }
+
+ SUBCASE("rename_theme_item") {
+ for (const StringName &name : names) {
+ for (const DataEntry &entry : valid_data) {
+ Ref<Theme> theme = memnew(Theme);
+ theme->set_theme_item(entry.type, valid_item_name, valid_type_name, entry.value);
+
+ ErrorDetector ed;
+ theme->rename_theme_item(entry.type, valid_item_name, name, valid_type_name);
+ CHECK(ed.has_error);
+ CHECK(theme->has_theme_item(entry.type, valid_item_name, valid_type_name));
+ CHECK_FALSE(theme->has_theme_item(entry.type, name, valid_type_name));
+ }
+ }
+ }
+}
+
+} // namespace TestTheme
+
+#endif // TEST_THEME_H