The Battle for Wesnoth  1.17.0-dev
iterator.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2021
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  , gui2::widget* widget
110  , const std::string& id
111  , const unsigned row
112  , const unsigned column)
113 {
114  BOOST_REQUIRE_NE(widget, static_cast<gui2::widget*>(nullptr));
115 
116  widget->set_id(id);
117  grid.set_child(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  gui2::grid* g = new gui2::grid(2, 2);
187  add_widget(grid, g, "1", 0, 0);
191 
196 
197  {
198  std::stringstream sstr;
199  lg::redirect_output_setter redirect_output(sstr);
200 
202  true
203  , true
204  , true>>
205  iterator(grid);
206 
207  while(iterator.next()) {
208  /* DO NOTHING */
209  }
210 
211  BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str());
212  }
213  {
214  std::stringstream sstr;
215  lg::redirect_output_setter redirect_output(sstr);
216 
218  true
219  , true
220  , true>>
221  iterator(grid);
222 
223  for( ; !iterator.at_end(); ++iterator) {
224  /* DO NOTHING */
225  }
226 
227  BOOST_CHECK_EQUAL(top_down_t_t_t_result(), sstr.str());
228  }
229  {
230  std::stringstream sstr;
231  lg::redirect_output_setter redirect_output(sstr);
232 
234  true
235  , true
236  , true>>
237  iterator(grid);
238 
239  while(iterator.next()) {
240  /* DO NOTHING */
241  }
242 
243  BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str());
244  }
245  {
246  std::stringstream sstr;
247  lg::redirect_output_setter redirect_output(sstr);
248 
250  true
251  , true
252  , true>>
253  iterator(grid);
254 
255  for( ; !iterator.at_end(); ++iterator) {
256  /* DO NOTHING */
257  }
258 
259  BOOST_CHECK_EQUAL(bottom_up_t_t_t_result(), sstr.str());
260  }
261 }
262 
263 BOOST_AUTO_TEST_CASE(test_gui2_iterator)
264 {
265  /**** Initialize the environment. *****/
267 
268  cache.clear_defines();
269  cache.add_define("EDITOR");
270  cache.add_define("MULTIPLAYER");
271 
272  lg::set_log_domain_severity("gui/iterator", lg::debug());
273  lg::timestamps(false);
274 
275  std::stringstream sstr;
276  lg::redirect_output_setter redirect_output(sstr);
277 
278  test_control();
279  test_grid();
280 
282 }
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
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:61
static void add_widget(gui2::grid &grid, gui2::widget *widget, const std::string &id, const unsigned row, const unsigned column)
Definition: iterator.cpp:108
logger & debug()
Definition: log.cpp:95
static std::string top_down_t_t_t_result()
Definition: iterator.cpp:43
void set_child(widget *widget, const unsigned row, const unsigned col, const unsigned flags, const unsigned border_size)
Sets a child in the grid.
Definition: grid.cpp:70
void clear_defines()
Clear stored defines map to default values.
double g
Definition: astarsearch.cpp:65
static tcache cache
Definition: minimap.cpp:124
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:535
The iterator class.
Definition: iterator.hpp:39
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:98
BOOST_AUTO_TEST_CASE(test_gui2_iterator)
Definition: iterator.cpp:263
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:61
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
Singleton class to manage game config file caching.