diff options
-rw-r--r-- | core/math/expression.h | 2 | ||||
-rw-r--r-- | doc/classes/Expression.xml | 2 | ||||
-rw-r--r-- | doc/classes/Node.xml | 2 | ||||
-rw-r--r-- | doc/classes/Texture2D.xml | 2 | ||||
-rw-r--r-- | editor/editor_feature_profile.cpp | 17 | ||||
-rw-r--r-- | editor/editor_feature_profile.h | 2 | ||||
-rw-r--r-- | editor/editor_node.cpp | 6 | ||||
-rw-r--r-- | platform/android/java/lib/res/values/dimens.xml | 4 | ||||
-rw-r--r-- | platform/android/java/lib/src/org/godotengine/godot/Godot.java | 6 | ||||
-rw-r--r-- | scene/resources/texture.h | 3 | ||||
-rw-r--r-- | tests/test_expression.h | 431 | ||||
-rw-r--r-- | tests/test_main.cpp | 1 |
12 files changed, 463 insertions, 15 deletions
diff --git a/core/math/expression.h b/core/math/expression.h index 59a9a2f4ed..f2cfe6b1a6 100644 --- a/core/math/expression.h +++ b/core/math/expression.h @@ -343,7 +343,7 @@ protected: public: Error parse(const String &p_expression, const Vector<String> &p_input_names = Vector<String>()); - Variant execute(Array p_inputs, Object *p_base = nullptr, bool p_show_error = true); + Variant execute(Array p_inputs = Array(), Object *p_base = nullptr, bool p_show_error = true); bool has_execute_failed() const; String get_error_text() const; diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml index fcd1aa43c0..f2611dc850 100644 --- a/doc/classes/Expression.xml +++ b/doc/classes/Expression.xml @@ -5,7 +5,7 @@ </brief_description> <description> An expression can be made of any arithmetic operation, built-in math function call, method call of a passed instance, or built-in type construction call. - An example expression text using the built-in math functions could be [code]sqrt(pow(3,2) + pow(4,2))[/code]. + An example expression text using the built-in math functions could be [code]sqrt(pow(3, 2) + pow(4, 2))[/code]. In the following example we use a [LineEdit] node to write our expression and show the result. [codeblock] onready var expression = Expression.new() diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 8f66c9df38..d31e336ea3 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -194,6 +194,7 @@ Finds a descendant of this node whose name matches [code]mask[/code] as in [method String.match] (i.e. case-sensitive, but [code]"*"[/code] matches zero or more characters and [code]"?"[/code] matches any single character except [code]"."[/code]). [b]Note:[/b] It does not match against the full path, just against individual node names. If [code]owned[/code] is [code]true[/code], this method only finds nodes whose owner is this node. This is especially important for scenes instantiated through a script, because those scenes don't have an owner. + [b]Note:[/b] As this method walks through all the descendants of the node, it is the slowest way to get a reference to another node. Whenever possible, consider using [method get_node] instead. To avoid using [method find_node] too often, consider caching the node reference into a variable. </description> </method> <method name="find_parent" qualifiers="const"> @@ -204,6 +205,7 @@ <description> Finds the first parent of the current node whose name matches [code]mask[/code] as in [method String.match] (i.e. case-sensitive, but [code]"*"[/code] matches zero or more characters and [code]"?"[/code] matches any single character except [code]"."[/code]). [b]Note:[/b] It does not match against the full path, just against individual node names. + [b]Note:[/b] As this method walks upwards in the scene tree, it can be slow in large, deeply nested scene trees. Whenever possible, consider using [method get_node] instead. To avoid using [method find_parent] too often, consider caching the node reference into a variable. </description> </method> <method name="get_child" qualifiers="const"> diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml index ffe806cef7..f283efdc3d 100644 --- a/doc/classes/Texture2D.xml +++ b/doc/classes/Texture2D.xml @@ -96,7 +96,7 @@ <return type="Image"> </return> <description> - Returns an [Image] with the data from this [Texture2D]. [Image]s can be accessed and manipulated directly. + Returns an [Image] that is a copy of data from this [Texture2D]. [Image]s can be accessed and manipulated directly. </description> </method> <method name="get_height" qualifiers="const"> diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp index f68cc3b323..418370a7c3 100644 --- a/editor/editor_feature_profile.cpp +++ b/editor/editor_feature_profile.cpp @@ -41,9 +41,9 @@ const char *EditorFeatureProfile::feature_names[FEATURE_MAX] = { TTRC("Script Editor"), TTRC("Asset Library"), TTRC("Scene Tree Editing"), - TTRC("Import Dock"), TTRC("Node Dock"), - TTRC("FileSystem and Import Docks") + TTRC("FileSystem Dock"), + TTRC("Import Dock"), }; const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { @@ -51,9 +51,9 @@ const char *EditorFeatureProfile::feature_identifiers[FEATURE_MAX] = { "script", "asset_lib", "scene_tree", - "import_dock", "node_dock", - "filesystem_dock" + "filesystem_dock", + "import_dock", }; void EditorFeatureProfile::set_disable_class(const StringName &p_class, bool p_disabled) { @@ -678,9 +678,16 @@ void EditorFeatureProfileManager::_update_selected_profile() { TreeItem *root = class_list->create_item(); TreeItem *features = class_list->create_item(root); + TreeItem *last_feature; features->set_text(0, TTR("Enabled Features:")); for (int i = 0; i < EditorFeatureProfile::FEATURE_MAX; i++) { - TreeItem *feature = class_list->create_item(features); + TreeItem *feature; + if (i == EditorFeatureProfile::FEATURE_IMPORT_DOCK) { + feature = class_list->create_item(last_feature); + } else { + feature = class_list->create_item(features); + last_feature = feature; + } feature->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); feature->set_text(0, TTRGET(EditorFeatureProfile::get_feature_name(EditorFeatureProfile::Feature(i)))); feature->set_selectable(0, true); diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h index 38413e35a2..d0d08c61f4 100644 --- a/editor/editor_feature_profile.h +++ b/editor/editor_feature_profile.h @@ -49,9 +49,9 @@ public: FEATURE_SCRIPT, FEATURE_ASSET_LIB, FEATURE_SCENE_TREE, - FEATURE_IMPORT_DOCK, FEATURE_NODE_DOCK, FEATURE_FILESYSTEM_DOCK, + FEATURE_IMPORT_DOCK, FEATURE_MAX }; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 8544bb8856..26281a232b 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -5344,9 +5344,11 @@ void EditorNode::_feature_profile_changed() { TabContainer *node_tabs = cast_to<TabContainer>(node_dock->get_parent()); TabContainer *fs_tabs = cast_to<TabContainer>(filesystem_dock->get_parent()); if (profile.is_valid()) { - import_tabs->set_tab_hidden(import_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); node_tabs->set_tab_hidden(node_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK)); - fs_tabs->set_tab_hidden(filesystem_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK)); + // The Import dock is useless without the FileSystem dock. Ensure the configuration is valid. + bool fs_dock_disabled = profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK); + fs_tabs->set_tab_hidden(filesystem_dock->get_index(), fs_dock_disabled); + import_tabs->set_tab_hidden(import_dock->get_index(), fs_dock_disabled || profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK)); main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); diff --git a/platform/android/java/lib/res/values/dimens.xml b/platform/android/java/lib/res/values/dimens.xml new file mode 100644 index 0000000000..9034dbbcc1 --- /dev/null +++ b/platform/android/java/lib/res/values/dimens.xml @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <dimen name="text_edit_height">48dp</dimen> +</resources> diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 1b55090451..524f32bf5e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -151,8 +151,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC private void setButtonPausedState(boolean paused) { mStatePaused = paused; - int stringResourceID = paused ? R.string.text_button_resume : - R.string.text_button_pause; + int stringResourceID = paused ? R.string.text_button_resume : R.string.text_button_pause; mPauseButton.setText(stringResourceID); } @@ -221,7 +220,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC // GodotEditText layout GodotEditText editText = new GodotEditText(activity); - editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, + (int)getResources().getDimension(R.dimen.text_edit_height))); // ...add to FrameLayout containerLayout.addView(editText); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index d439d34c95..fd213859b7 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -632,11 +632,12 @@ class AnimatedTexture : public Texture2D { //use readers writers lock for this, since its far more times read than written to RWLock *rw_lock; -private: +public: enum { MAX_FRAMES = 256 }; +private: RID proxy_ph; RID proxy; diff --git a/tests/test_expression.h b/tests/test_expression.h new file mode 100644 index 0000000000..85d37d1460 --- /dev/null +++ b/tests/test_expression.h @@ -0,0 +1,431 @@ +/*************************************************************************/ +/* test_expression.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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_EXPRESSION_H +#define TEST_EXPRESSION_H + +#include "core/math/expression.h" + +#include "tests/test_macros.h" + +namespace TestExpression { + +TEST_CASE("[Expression] Integer arithmetic") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("-123456") == OK, + "Integer identity should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == -123456, + "Integer identity should return the expected result."); + + CHECK_MESSAGE( + expression.parse("2 + 3") == OK, + "Integer addition should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 5, + "Integer addition should return the expected result."); + + CHECK_MESSAGE( + expression.parse("999999999999 + 999999999999") == OK, + "Large integer addition should parse successfully."); + CHECK_MESSAGE( + int64_t(expression.execute()) == 1'999'999'999'998, + "Large integer addition should return the expected result."); + + CHECK_MESSAGE( + expression.parse("25 / 10") == OK, + "Integer / integer division should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 2, + "Integer / integer divsion should return the expected result."); + + CHECK_MESSAGE( + expression.parse("2 * (6 + 14) / 2 - 5") == OK, + "Integer multiplication-addition-subtraction-division should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 15, + "Integer multiplication-addition-subtraction-division should return the expected result."); +} + +TEST_CASE("[Expression] Floating-point arithmetic") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("-123.456") == OK, + "Float identity should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), -123.456), + "Float identity should return the expected result."); + + CHECK_MESSAGE( + expression.parse("2.0 + 3.0") == OK, + "Float addition should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 5), + "Float addition should return the expected result."); + + CHECK_MESSAGE( + expression.parse("3.0 / 10") == OK, + "Float / integer division should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 0.3), + "Float / integer divsion should return the expected result."); + + CHECK_MESSAGE( + expression.parse("3 / 10.0") == OK, + "Basic integer / float division should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 0.3), + "Basic integer / float divsion should return the expected result."); + + CHECK_MESSAGE( + expression.parse("3.0 / 10.0") == OK, + "Float / float division should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 0.3), + "Float / float divsion should return the expected result."); + + CHECK_MESSAGE( + expression.parse("2.5 * (6.0 + 14.25) / 2.0 - 5.12345") == OK, + "Float multiplication-addition-subtraction-division should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 20.18905), + "Float multiplication-addition-subtraction-division should return the expected result."); +} + +TEST_CASE("[Expression] Scientific notation") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("2.e5") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 200'000), + "The expression should return the expected result."); + + // The middle "e" is ignored here. + CHECK_MESSAGE( + expression.parse("2e5") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 25), + "The expression should return the expected result."); + + CHECK_MESSAGE( + expression.parse("2e.5") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 2), + "The expression should return the expected result."); +} + +TEST_CASE("[Expression] Built-in functions") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("sqrt(pow(3, 2) + pow(4, 2))") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 5, + "`sqrt(pow(3, 2) + pow(4, 2))` should return the expected result."); + + CHECK_MESSAGE( + expression.parse("stepify(sin(0.5), 0.01)") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + Math::is_equal_approx(float(expression.execute()), 0.48), + "`stepify(sin(0.5), 0.01)` should return the expected result."); + + CHECK_MESSAGE( + expression.parse("pow(2.0, -2500)") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + Math::is_zero_approx(float(expression.execute())), + "`pow(2.0, -2500)` should return the expected result (asymptotically zero)."); +} + +TEST_CASE("[Expression] Boolean expressions") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("24 >= 12") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + bool(expression.execute()), + "The boolean expression should evaluate to `true`."); + + CHECK_MESSAGE( + expression.parse("1.0 < 1.25 && 1.25 < 2.0") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + bool(expression.execute()), + "The boolean expression should evaluate to `true`."); + + CHECK_MESSAGE( + expression.parse("!2") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + !bool(expression.execute()), + "The boolean expression should evaluate to `false`."); + + CHECK_MESSAGE( + expression.parse("!!2") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + bool(expression.execute()), + "The boolean expression should evaluate to `true`."); + + CHECK_MESSAGE( + expression.parse("!0") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + bool(expression.execute()), + "The boolean expression should evaluate to `true`."); + + CHECK_MESSAGE( + expression.parse("!!0") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + !bool(expression.execute()), + "The boolean expression should evaluate to `false`."); + + CHECK_MESSAGE( + expression.parse("2 && 5") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + bool(expression.execute()), + "The boolean expression should evaluate to `true`."); + + CHECK_MESSAGE( + expression.parse("0 || 0") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + !bool(expression.execute()), + "The boolean expression should evaluate to `false`."); + + CHECK_MESSAGE( + expression.parse("(2 <= 4) && (2 > 5)") == OK, + "The boolean expression should parse successfully."); + CHECK_MESSAGE( + !bool(expression.execute()), + "The boolean expression should evaluate to `false`."); +} + +TEST_CASE("[Expression] Expressions with variables") { + Expression expression; + + PackedStringArray parameter_names; + parameter_names.push_back("foo"); + parameter_names.push_back("bar"); + CHECK_MESSAGE( + expression.parse("foo + bar + 50", parameter_names) == OK, + "The expression should parse successfully."); + Array values; + values.push_back(60); + values.push_back(20); + CHECK_MESSAGE( + int(expression.execute(values)) == 130, + "The expression should return the expected value."); + + PackedStringArray parameter_names_invalid; + parameter_names_invalid.push_back("foo"); + parameter_names_invalid.push_back("baz"); // Invalid parameter name. + CHECK_MESSAGE( + expression.parse("foo + bar + 50", parameter_names_invalid) == OK, + "The expression should parse successfully."); + Array values_invalid; + values_invalid.push_back(60); + values_invalid.push_back(20); + // Invalid parameters will parse successfully but print an error message when executing. + ERR_PRINT_OFF; + CHECK_MESSAGE( + int(expression.execute(values_invalid)) == 0, + "The expression should return the expected value."); + ERR_PRINT_ON; + + // Mismatched argument count (more values than parameters). + PackedStringArray parameter_names_mismatch; + parameter_names_mismatch.push_back("foo"); + parameter_names_mismatch.push_back("bar"); + CHECK_MESSAGE( + expression.parse("foo + bar + 50", parameter_names_mismatch) == OK, + "The expression should parse successfully."); + Array values_mismatch; + values_mismatch.push_back(60); + values_mismatch.push_back(20); + values_mismatch.push_back(110); + CHECK_MESSAGE( + int(expression.execute(values_mismatch)) == 130, + "The expression should return the expected value."); + + // Mismatched argument count (more parameters than values). + PackedStringArray parameter_names_mismatch2; + parameter_names_mismatch2.push_back("foo"); + parameter_names_mismatch2.push_back("bar"); + parameter_names_mismatch2.push_back("baz"); + CHECK_MESSAGE( + expression.parse("foo + bar + baz + 50", parameter_names_mismatch2) == OK, + "The expression should parse successfully."); + Array values_mismatch2; + values_mismatch2.push_back(60); + values_mismatch2.push_back(20); + // Having more parameters than values will parse successfully but print an + // error message when executing. + ERR_PRINT_OFF; + CHECK_MESSAGE( + int(expression.execute(values_mismatch2)) == 0, + "The expression should return the expected value."); + ERR_PRINT_ON; +} + +TEST_CASE("[Expression] Invalid expressions") { + Expression expression; + + CHECK_MESSAGE( + expression.parse("\\") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("0++") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("()") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("()()") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("() - ()") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("() * 12345") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("() * 12345") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("123'456") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); + + CHECK_MESSAGE( + expression.parse("123\"456") == ERR_INVALID_PARAMETER, + "The expression shouldn't parse successfully."); +} + +TEST_CASE("[Expression] Unusual expressions") { + Expression expression; + + // Redundant parentheses don't cause a parse error as long as they're matched. + CHECK_MESSAGE( + expression.parse("(((((((((((((((666)))))))))))))))") == OK, + "The expression should parse successfully."); + + // Using invalid identifiers doesn't cause a parse error. + ERR_PRINT_OFF; + CHECK_MESSAGE( + expression.parse("hello + hello") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 0, + "The expression should return the expected result."); + ERR_PRINT_ON; + + ERR_PRINT_OFF; + CHECK_MESSAGE( + expression.parse("$1.00 + €5") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 0, + "The expression should return the expected result."); + ERR_PRINT_ON; + + // Commas can't be used as a decimal parameter. + CHECK_MESSAGE( + expression.parse("123,456") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 123, + "The expression should return the expected result."); + + // Spaces can't be used as a separator for large numbers. + CHECK_MESSAGE( + expression.parse("123 456") == OK, + "The expression should parse successfully."); + CHECK_MESSAGE( + int(expression.execute()) == 123, + "The expression should return the expected result."); + + // Division by zero is accepted, even though it prints an error message normally. + CHECK_MESSAGE( + expression.parse("-25.4 / 0") == OK, + "The expression should parse successfully."); + ERR_PRINT_OFF; + CHECK_MESSAGE( + Math::is_zero_approx(float(expression.execute())), + "`-25.4 / 0` should return 0."); + ERR_PRINT_ON; + + CHECK_MESSAGE( + expression.parse("0 / 0") == OK, + "The expression should parse successfully."); + ERR_PRINT_OFF; + CHECK_MESSAGE( + int(expression.execute()) == 0, + "`0 / 0` should return 0."); + ERR_PRINT_ON; + + // The tests below currently crash the engine. + // + //CHECK_MESSAGE( + // expression.parse("(-9223372036854775807 - 1) % -1") == OK, + // "The expression should parse successfully."); + //CHECK_MESSAGE( + // int64_t(expression.execute()) == 0, + // "`(-9223372036854775807 - 1) % -1` should return the expected result."); + // + //CHECK_MESSAGE( + // expression.parse("(-9223372036854775807 - 1) / -1") == OK, + // "The expression should parse successfully."); + //CHECK_MESSAGE( + // int64_t(expression.execute()) == 0, + // "`(-9223372036854775807 - 1) / -1` should return the expected result."); +} + +} // namespace TestExpression + +#endif // TEST_EXPRESSION_H diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 892cc26a51..43c1ef331f 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -36,6 +36,7 @@ #include "test_basis.h" #include "test_class_db.h" #include "test_color.h" +#include "test_expression.h" #include "test_gdscript.h" #include "test_gradient.h" #include "test_gui.h" |