Browse Source

Add tests for control to test anchoring and minimum size

girdenis-p 9 months ago
parent
commit
577ee919d4
1 changed files with 209 additions and 1 deletions
  1. 209 1
      tests/scene/test_control.h

+ 209 - 1
tests/scene/test_control.h

@@ -37,7 +37,7 @@
 
 namespace TestControl {
 
-TEST_CASE("[SceneTree][Control]") {
+TEST_CASE("[SceneTree][Control] Transforms") {
 	SUBCASE("[Control][Global Transform] Global Transform should be accessible while not in SceneTree.") { // GH-79453
 		Control *test_node = memnew(Control);
 		Control *test_child = memnew(Control);
@@ -112,6 +112,214 @@ TEST_CASE("[SceneTree][Control] Focus") {
 	memdelete(ctrl);
 }
 
+TEST_CASE("[SceneTree][Control] Anchoring") {
+	Control *test_control = memnew(Control);
+	Control *test_child = memnew(Control);
+	test_control->add_child(test_child);
+	test_control->set_size(Size2(2, 2));
+	Window *root = SceneTree::get_singleton()->get_root();
+	root->add_child(test_control);
+
+	SUBCASE("Anchoring without offsets") {
+		test_child->set_anchor(SIDE_RIGHT, 0.75);
+		test_child->set_anchor(SIDE_BOTTOM, 0.1);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(1.5, 0.2)),
+				"With no LEFT or TOP anchors, positive RIGHT and BOTTOM anchors should be proportional to the size.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(0, 0)),
+				"With positive RIGHT and BOTTOM anchors set and no LEFT or TOP anchors, the position should not change.");
+
+		test_child->set_anchor(SIDE_LEFT, 0.5);
+		test_child->set_anchor(SIDE_TOP, 0.01);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(0.5, 0.18)),
+				"With all anchors set, the size should fit between all four anchors.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(1, 0.02)),
+				"With all anchors set, the LEFT and TOP anchors should proportional to the position.");
+	}
+
+	SUBCASE("Anchoring with offsets") {
+		test_child->set_offset(SIDE_RIGHT, 0.33);
+		test_child->set_offset(SIDE_BOTTOM, 0.2);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(0.33, 0.2)),
+				"With no anchors or LEFT or TOP offsets set, the RIGHT and BOTTOM offsets should be equal to size.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(0, 0)),
+				"With only positive RIGHT and BOTTOM offsets set, the position should not change.");
+
+		test_child->set_offset(SIDE_LEFT, 0.1);
+		test_child->set_offset(SIDE_TOP, 0.05);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(0.23, 0.15)),
+				"With no anchors set, the size should fit between all four offsets.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(0.1, 0.05)),
+				"With no anchors set, the LEFT and TOP offsets should be equal to the position.");
+
+		test_child->set_anchor(SIDE_RIGHT, 0.5);
+		test_child->set_anchor(SIDE_BOTTOM, 0.3);
+		test_child->set_anchor(SIDE_LEFT, 0.2);
+		test_child->set_anchor(SIDE_TOP, 0.1);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
+				"Anchors adjust size first then it is affected by offsets.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(0.5, 0.25)),
+				"Anchors adjust positions first then it is affected by offsets.");
+
+		test_child->set_offset(SIDE_RIGHT, -0.1);
+		test_child->set_offset(SIDE_BOTTOM, -0.01);
+		test_child->set_offset(SIDE_LEFT, -0.33);
+		test_child->set_offset(SIDE_TOP, -0.16);
+		CHECK_MESSAGE(
+				test_child->get_size().is_equal_approx(Vector2(0.83, 0.55)),
+				"Keeping offset distance equal when changing offsets, keeps size equal.");
+		CHECK_MESSAGE(
+				test_child->get_position().is_equal_approx(Vector2(0.07, 0.04)),
+				"Negative offsets move position in top left direction.");
+	}
+
+	SUBCASE("Anchoring is preserved on parent size changed") {
+		test_child->set_offset(SIDE_RIGHT, -0.05);
+		test_child->set_offset(SIDE_BOTTOM, 0.1);
+		test_child->set_offset(SIDE_LEFT, 0.05);
+		test_child->set_offset(SIDE_TOP, 0.1);
+		test_child->set_anchor(SIDE_RIGHT, 0.3);
+		test_child->set_anchor(SIDE_BOTTOM, 0.85);
+		test_child->set_anchor(SIDE_LEFT, 0.2);
+		test_child->set_anchor(SIDE_TOP, 0.55);
+		CHECK(test_child->get_rect().is_equal_approx(
+				Rect2(Vector2(0.45, 1.2), Size2(0.1, 0.6))));
+
+		test_control->set_size(Size2(4, 1));
+		CHECK(test_child->get_rect().is_equal_approx(
+				Rect2(Vector2(0.85, 0.65), Size2(0.3, 0.3))));
+	}
+
+	memdelete(test_child);
+	memdelete(test_control);
+}
+
+TEST_CASE("[SceneTree][Control] Custom minimum size") {
+	Control *test_control = memnew(Control);
+	test_control->set_custom_minimum_size(Size2(4, 2));
+	Window *root = SceneTree::get_singleton()->get_root();
+	root->add_child(test_control);
+	CHECK_MESSAGE(
+			test_control->get_size().is_equal_approx(Vector2(4, 2)),
+			"Size increases to match custom minimum size.");
+
+	test_control->set_size(Size2(5, 4));
+	CHECK_MESSAGE(
+			test_control->get_size().is_equal_approx(Vector2(5, 4)),
+			"Size does not change if above custom minimum size.");
+
+	test_control->set_size(Size2(1, 1));
+	CHECK_MESSAGE(
+			test_control->get_size().is_equal_approx(Vector2(4, 2)),
+			"Size matches minimum size if set below custom minimum size.");
+
+	test_control->set_size(Size2(3, 3));
+	CHECK_MESSAGE(
+			test_control->get_size().is_equal_approx(Vector2(4, 3)),
+			"Adjusts only x axis size if x is below custom minimum size.");
+
+	test_control->set_size(Size2(10, 0.1));
+	CHECK_MESSAGE(
+			test_control->get_size().is_equal_approx(Vector2(10, 2)),
+			"Adjusts only y axis size if y is below custom minimum size.");
+
+	memdelete(test_control);
+}
+
+TEST_CASE("[SceneTree][Control] Grow direction") {
+	Control *test_control = memnew(Control);
+	test_control->set_size(Size2(1, 1));
+	Window *root = SceneTree::get_singleton()->get_root();
+	root->add_child(test_control);
+
+	SUBCASE("Defaults") {
+		CHECK(test_control->get_h_grow_direction() == Control::GROW_DIRECTION_END);
+		CHECK(test_control->get_v_grow_direction() == Control::GROW_DIRECTION_END);
+	}
+
+	SIGNAL_WATCH(test_control, SNAME("minimum_size_changed"))
+	Array signal_args;
+	signal_args.push_back(Array());
+
+	SUBCASE("Horizontal grow direction begin") {
+		test_control->set_h_grow_direction(Control::GROW_DIRECTION_BEGIN);
+		test_control->set_custom_minimum_size(Size2(2, 2));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args)
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(-1, 0), Size2(2, 2))),
+				"Expand leftwards.");
+	}
+
+	SUBCASE("Vertical grow direction begin") {
+		test_control->set_v_grow_direction(Control::GROW_DIRECTION_BEGIN);
+		test_control->set_custom_minimum_size(Size2(4, 3));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args);
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(0, -2), Size2(4, 3))),
+				"Expand upwards.");
+	}
+
+	SUBCASE("Horizontal grow direction end") {
+		test_control->set_h_grow_direction(Control::GROW_DIRECTION_END);
+		test_control->set_custom_minimum_size(Size2(5, 3));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args);
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(0, 0), Size2(5, 3))),
+				"Expand rightwards.");
+	}
+
+	SUBCASE("Vertical grow direction end") {
+		test_control->set_v_grow_direction(Control::GROW_DIRECTION_END);
+		test_control->set_custom_minimum_size(Size2(4, 4));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args);
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(0, 0), Size2(4, 4))),
+				"Expand downwards.");
+		;
+	}
+
+	SUBCASE("Horizontal grow direction both") {
+		test_control->set_h_grow_direction(Control::GROW_DIRECTION_BOTH);
+		test_control->set_custom_minimum_size(Size2(2, 4));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args);
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(-0.5, 0), Size2(2, 4))),
+				"Expand equally leftwards and rightwards.");
+	}
+
+	SUBCASE("Vertical grow direction both") {
+		test_control->set_v_grow_direction(Control::GROW_DIRECTION_BOTH);
+		test_control->set_custom_minimum_size(Size2(6, 3));
+		SceneTree::get_singleton()->process(0);
+		SIGNAL_CHECK("minimum_size_changed", signal_args);
+		CHECK_MESSAGE(
+				test_control->get_rect().is_equal_approx(
+						Rect2(Vector2(0, -1), Size2(6, 3))),
+				"Expand equally upwards and downwards.");
+	}
+
+	memdelete(test_control);
+}
+
 } // namespace TestControl
 
 #endif // TEST_CONTROL_H