2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file test_window_desc.cpp Test WindowDescs for valid widget parts. */
10 #include "../stdafx.h"
12 #include "../3rdparty/catch2/catch.hpp"
14 #include "mock_environment.h"
16 #include "../window_gui.h"
19 * List of WindowDescs. Defined in window.cpp but not exposed as this unit-test is the only other place that needs it.
20 * WindowDesc is a self-registering class so all WindowDescs will be included in the list.
22 extern std::vector
<WindowDesc
*> *_window_descs
;
25 class WindowDescTestsFixture
{
27 MockEnvironment
&mock
= MockEnvironment::Instance();
31 TEST_CASE("WindowDesc - ini_key uniqueness")
33 std::set
<std::string
> seen
;
35 for (const WindowDesc
*window_desc
: *_window_descs
) {
37 if (window_desc
->ini_key
== nullptr) continue;
39 CAPTURE(window_desc
->ini_key
);
40 CHECK((seen
.find(window_desc
->ini_key
) == std::end(seen
)));
42 seen
.insert(window_desc
->ini_key
);
46 TEST_CASE("WindowDesc - ini_key validity")
48 const WindowDesc
*window_desc
= GENERATE(from_range(std::begin(*_window_descs
), std::end(*_window_descs
)));
50 bool has_inikey
= window_desc
->ini_key
!= nullptr;
51 bool has_widget
= std::any_of(std::begin(window_desc
->nwid_parts
), std::end(window_desc
->nwid_parts
), [](const NWidgetPart
&part
) { return part
.type
== WWT_DEFSIZEBOX
|| part
.type
== WWT_STICKYBOX
; });
53 INFO(fmt::format("{}:{}", window_desc
->source_location
.file_name(), window_desc
->source_location
.line()));
57 CHECK((has_widget
== has_inikey
));
61 * Test if a NWidgetTree is properly closed, meaning the number of container-type parts matches the number of
62 * EndContainer() parts.
63 * @param nwid_parts Span of nested widget parts.
64 * @return True iff nested tree is properly closed.
66 static bool IsNWidgetTreeClosed(std::span
<const NWidgetPart
> nwid_parts
)
69 for (const auto nwid
: nwid_parts
) {
70 if (IsContainerWidgetType(nwid
.type
)) ++depth
;
71 if (nwid
.type
== WPT_ENDCONTAINER
) --depth
;
76 TEST_CASE("WindowDesc - NWidgetParts properly closed")
78 const WindowDesc
*window_desc
= GENERATE(from_range(std::begin(*_window_descs
), std::end(*_window_descs
)));
80 INFO(fmt::format("{}:{}", window_desc
->source_location
.file_name(), window_desc
->source_location
.line()));
82 CHECK(IsNWidgetTreeClosed(window_desc
->nwid_parts
));
85 TEST_CASE_METHOD(WindowDescTestsFixture
, "WindowDesc - NWidgetPart validity")
87 const WindowDesc
*window_desc
= GENERATE(from_range(std::begin(*_window_descs
), std::end(*_window_descs
)));
89 INFO(fmt::format("{}:{}", window_desc
->source_location
.file_name(), window_desc
->source_location
.line()));
91 NWidgetStacked
*shade_select
= nullptr;
92 std::unique_ptr
<NWidgetBase
> root
= nullptr;
94 REQUIRE_NOTHROW(root
= MakeWindowNWidgetTree(window_desc
->nwid_parts
, &shade_select
));
95 CHECK((root
!= nullptr));