The Battle for Wesnoth  1.17.4+dev
iterator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2022
3  by Mark de Wever <koraq@xs4all.nl>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #define GETTEXT_DOMAIN "wesnoth-lib"
17 
18 #include <boost/test/unit_test.hpp>
19 
20 #include "config.hpp"
21 #include "config_cache.hpp"
23 #include "gui/widgets/label.hpp"
24 #include "gui/widgets/grid.hpp"
25 
26 #include <iostream>
27 #include <sstream>
28 #include <typeinfo>
29 
30 /*
31  * In the unit tests we use a widget tree that looks like:
32  *
33  * [0]
34  * \
35  * [1|2|3|4]
36  * \
37  * [5|6|7|8]
38  *
39  * Where widgets 0 and 1 are a grid and the rest of the widgets a label.
40  * The unit tests traverse the tree.
41  */
42 
43 static std::string top_down_t_t_t_result()
44 {
45  static const std::string result =
46  "At '0'. Iterate widget: reached the end. Iterate grid: failed. "
47  "Iterate child: proceed. Down and visit '1'.\n"
48  "At '1'. Iterate widget: reached the end. Iterate grid: failed. "
49  "Iterate child: proceed. Down and visit '5'.\n"
50  "At '5'. Iterate widget: reached the end. Iterate grid: failed. "
51  "Iterate child: reached the end. Up widget '5'. "
52  "Iterate: reached '6'. Down and visit '6'.\n"
53  "At '6'. Iterate widget: reached the end. Iterate grid: failed. "
54  "Iterate child: reached the end. Up widget '6'. "
55  "Iterate: reached '7'. Down and visit '7'.\n"
56  "At '7'. Iterate widget: reached the end. Iterate grid: failed. "
57  "Iterate child: reached the end. Up widget '7'. "
58  "Iterate: reached '8'. Down and visit '8'.\n"
59  "At '8'. Iterate widget: reached the end. Iterate grid: failed. "
60  "Iterate child: reached the end. Up widget '8'. "
61  "Iterate: failed. Up widget '1'. "
62  "Iterate: reached '2'. Down and visit '2'.\n"
63  "At '2'. Iterate widget: reached the end. Iterate grid: failed. "
64  "Iterate child: reached the end. Up widget '2'. "
65  "Iterate: reached '3'. Down and visit '3'.\n"
66  "At '3'. Iterate widget: reached the end. Iterate grid: failed. "
67  "Iterate child: reached the end. Up widget '3'. "
68  "Iterate: reached '4'. Down and visit '4'.\n"
69  "At '4'. Iterate widget: reached the end. Iterate grid: failed. "
70  "Iterate child: reached the end. Up widget '4'. "
71  "Iterate: failed. Finished iteration.\n";
72 
73  return result;
74 }
75 
76 static std::string bottom_up_t_t_t_result()
77 {
78  static const std::string result =
79  "Constructor: Down widget '1'. Down widget '5'. Finished at '5'.\n"
80  "At '5'. Iterate widget: reached the end. Iterate grid: failed. "
81  "Iterate child: Up '1'. Iterate child: visit '1'. "
82  "Down widget '6'. Visit '6'.\n"
83  "At '6'. Iterate widget: reached the end. Iterate grid: failed. "
84  "Iterate child: Up '1'. Iterate child: visit '1'. "
85  "Down widget '7'. Visit '7'.\n"
86  "At '7'. Iterate widget: reached the end. Iterate grid: failed. "
87  "Iterate child: Up '1'. Iterate child: visit '1'. "
88  "Down widget '8'. Visit '8'.\n"
89  "At '8'. Iterate widget: reached the end. Iterate grid: failed. "
90  "Iterate child: Up '1'. Iterate child: reached the end. Visit '1'.\n"
91  "At '1'. Iterate widget: reached the end. Iterate grid: failed. "
92  "Iterate child: Up '0'. Iterate child: visit '0'. "
93  "Down widget '2'. Visit '2'.\n"
94  "At '2'. Iterate widget: reached the end. Iterate grid: failed. "
95  "Iterate child: Up '0'. Iterate child: visit '0'. "
96  "Down widget '3'. Visit '3'.\n"
97  "At '3'. Iterate widget: reached the end. Iterate grid: failed. "
98  "Iterate child: Up '0'. Iterate child: visit '0'. "
99  "Down widget '4'. Visit '4'.\n"
100  "At '4'. Iterate widget: reached the end. Iterate grid: failed. "
101  "Iterate child: Up '0'. Iterate child: reached the end. Visit '0'.\n"
102  "At '0'. Iterate widget: reached the end. Iterate grid: failed. "
103  "Iterate child: Finished iteration.\n";
104 
105  return result;
106 }
107 
109  , std::unique_ptr<gui2::widget> widget
110  , const std::string& id
111  , const unsigned row
112  , const unsigned column)
113 {
114  BOOST_REQUIRE_NE(widget.get(), static_cast<gui2::widget*>(nullptr));
115 
116  widget->set_id(id);
117  grid.set_child(std::move(widget)
118  , row
119  , column
122  , 0);
123 }
124 
125 template<class T>
126 static void test_control(T&& control)
127 {
128  {
130  true
131  , true
132  , true>>
133  iterator(control);
134 
135  /***** INITIAL STATE *****/
136 
137  BOOST_CHECK_EQUAL(iterator.at_end(), false);
138 
139  BOOST_CHECK_EQUAL(&*iterator, &control);
140 
141  /***** POST END *****/
142 
143  BOOST_CHECK_EQUAL(iterator.next(), false);
144 
145  BOOST_CHECK_EQUAL(iterator.at_end(), true);
146 
147  }
148  {
150  false
151  , true
152  , true>>
153  iterator(control);
154 
155  /***** INITIAL STATE *****/
156 
157  BOOST_CHECK_EQUAL(iterator.at_end(), true);
158  }
159 
160  {
162  BOOST_CHECK_EQUAL(iterator.at_end(), false);
163  }
164  {
166  BOOST_CHECK_EQUAL(iterator.at_end(), true);
167  }
168 }
169 
170 static void test_control()
171 {
172  /* Could add more widgets to the list. */
174 
175 }
176 
177 static void test_grid()
178 {
179  /* An empty grid behaves the same as a control so test here. */
181 
182  /* Test the child part here. */
183  gui2::grid grid(2 ,2);
184  grid.set_id("0");
185 
186  auto g = std::make_unique<gui2::grid>(2, 2);
187  gui2::grid* gptr = g.get();
188 
189  add_widget(grid, std::move(g), "1", 0, 0);
190  add_widget(grid, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "2", 1, 0);
191  add_widget(grid, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "3", 0, 1);
192  add_widget(grid, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "4", 1, 1);
193 
194  add_widget(*gptr, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "5", 0, 0);
195  add_widget(*gptr, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "6", 1, 0);
196  add_widget(*gptr, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "7", 0, 1);
197  add_widget(*gptr, std::make_unique<gui2::label>(gui2::implementation::builder_label(config())), "8", 1, 1);
198 
199  {
200  std::stringstream sstr;
201  lg::redirect_output_setter redirect_output(sstr);
202 
204  true
205  , true
206  , true>>
207  iterator(grid);
208 
209  while(iterator.next()) {
210  /* DO NOTHING */
211  }
212 
213  BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str());
214  }
215  {
216  std::stringstream sstr;
217  lg::redirect_output_setter redirect_output(sstr);
218 
220  true
221  , true
222  , true>>
223  iterator(grid);
224 
225  for( ; !iterator.at_end(); ++iterator) {
226  /* DO NOTHING */
227  }
228 
229  BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str());
230  }
231  {
232  std::stringstream sstr;
233  lg::redirect_output_setter redirect_output(sstr);
234 
236  true
237  , true
238  , true>>
239  iterator(grid);
240 
241  while(iterator.next()) {
242  /* DO NOTHING */
243  }
244 
245  BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str());
246  }
247  {
248  std::stringstream sstr;
249  lg::redirect_output_setter redirect_output(sstr);
250 
252  true
253  , true
254  , true>>
255  iterator(grid);
256 
257  for( ; !iterator.at_end(); ++iterator) {
258  /* DO NOTHING */
259  }
260 
261  BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str());
262  }
263 }
264 
265 BOOST_AUTO_TEST_CASE(test_gui2_iterator)
266 {
267  /**** Initialize the environment. *****/
269 
270  cache.clear_defines();
271  cache.add_define("EDITOR");
272  cache.add_define("MULTIPLAYER");
273 
274  lg::set_log_domain_severity("gui/iterator", lg::debug());
275  lg::timestamps(false);
276 
277  std::stringstream sstr;
278  lg::redirect_output_setter redirect_output(sstr);
279 
280  test_control();
281  test_grid();
282 
284 }
static config_cache & instance()
Get reference to the singleton object.
static void test_control(T &&control)
Definition: iterator.cpp:126
void timestamps(bool t)
Definition: log.cpp:74
Base class for all widgets.
Definition: widget.hpp:49
A label displays a text, the text can be wrapped but no scrollbars are provided.
Definition: label.hpp:57
static void add_widget(gui2::grid &grid, std::unique_ptr< gui2::widget > widget, const std::string &id, const unsigned row, const unsigned column)
Definition: iterator.cpp:108
Helper class to redirect the output of the logger in a certain scope.
Definition: log.hpp:78
Definitions for the interface to Wesnoth Markup Language (WML).
Base container class.
Definition: grid.hpp:31
bool at_end() const
Has the iterator reached the end?
Definition: iterator.hpp:58
logger & debug()
Definition: log.cpp:95
static std::string top_down_t_t_t_result()
Definition: iterator.cpp:43
void clear_defines()
Clear stored defines map to default values.
double g
Definition: astarsearch.cpp:65
static tcache cache
Definition: minimap.cpp:125
static const unsigned HORIZONTAL_GROW_SEND_TO_CLIENT
Definition: grid.hpp:56
static const unsigned VERTICAL_GROW_SEND_TO_CLIENT
Definition: grid.hpp:49
bool set_log_domain_severity(const std::string &name, int severity)
Definition: log.cpp:117
bool grid()
Definition: general.cpp:562
The iterator class.
Definition: iterator.hpp:36
logger & warn()
Definition: log.cpp:83
static std::string bottom_up_t_t_t_result()
Definition: iterator.cpp:76
void set_id(const std::string &id)
Definition: widget.cpp:99
BOOST_AUTO_TEST_CASE(test_gui2_iterator)
Definition: iterator.cpp:265
Contains the base iterator class for the gui2 widgets.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:60
static void test_grid()
Definition: iterator.cpp:177
void add_define(const std::string &define)
Add a entry to preproc defines map.
std::string::const_iterator iterator
Definition: tokenizer.hpp:25
void set_child(std::unique_ptr< widget > widget, const unsigned row, const unsigned col, const unsigned flags, const unsigned border_size)
Sets a child in the grid.
Definition: grid.cpp:71
Singleton class to manage game config file caching.