The Battle for Wesnoth  1.19.5+dev
test_config_cache.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
3  by Pauli Nieminen <paniemin@cc.hut.fi>
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 #include <boost/test/unit_test.hpp>
17 
18 #define GETTEXT_DOMAIN "wesnoth-test"
19 
20 
21 #include "config_cache.hpp"
22 #include "config.hpp"
23 #include "game_config.hpp"
24 #include "language.hpp"
25 #include "log.hpp"
26 #include "game_version.hpp"
27 
29 
30 #include <functional>
31 
32 
34 {
35  preproc_map defines_map;
36 
37 #if defined(__APPLE__)
38  defines_map["APPLE"] = preproc_define();
39 #endif
40 
41  defines_map["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
42 
43  return defines_map;
44 
45 }
46 
47 
48 /**
49  * Used to make distinct singleton for testing it
50  * because other tests will need original one to load data
51  **/
54 
55  public:
56  static test_config_cache& instance() ;
57 
58  void set_force_invalid_cache(bool force)
59  {
61  }
62 };
63 
65  static test_config_cache * cache_ = new test_config_cache;
66  return *cache_;
67 }
68 
69 /**
70  * Used to redirect defines settings to test cache
71  **/
73 
76  {
78  }
80  {
82  }
86 };
87 
88 BOOST_AUTO_TEST_CASE( test_preproc_defines )
89 {
91  const preproc_map& test_defines = cache.get_preproc_map();
92  preproc_map defines_map(setup_test_preproc_map());
93 
94  // check initial state
95  BOOST_REQUIRE_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
96  defines_map.begin() ,defines_map.end());
97 
98  // scoped
99  {
100  test_scoped_define test("TEST");
101  defines_map["TEST"] = preproc_define();
102 
103  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
104  defines_map.begin() ,defines_map.end());
105  defines_map.erase("TEST");
106  }
107  // Check scoped remove
108 
109  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
110  defines_map.begin() ,defines_map.end());
111 
112  // Manual add define
113  cache.add_define("TEST");
114  defines_map["TEST"] = preproc_define();
115  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
116  defines_map.begin() ,defines_map.end());
117 
118  // Manual remove define
119  cache.remove_define("TEST");
120  defines_map.erase("TEST");
121  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
122  defines_map.begin() ,defines_map.end());
123 }
124 
125 BOOST_AUTO_TEST_CASE( test_config_cache_defaults )
126 {
128  preproc_map defines_map(setup_test_preproc_map());
129 
130  const preproc_map& test_defines = cache.get_preproc_map();
131  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
132  defines_map.begin() ,defines_map.end());
133 }
134 
135 
137 
138  const std::string test_data_path("data/test/test/_main.cfg");
139 
141 {
142  config test_config;
143  config* child = &test_config.add_child("textdomain");
144  (*child)["name"] = GETTEXT_DOMAIN;
145 
146  child = &test_config.add_child("test_key");
147  (*child)["define"] = "test";
148  return test_config;
149 }
150 
151 
152 BOOST_AUTO_TEST_CASE( test_load_config )
153 {
154 
155  config test_config = setup_test_config();
156  config cached_config;
157  cache.get_config(test_data_path, cached_config);
158  BOOST_CHECK_EQUAL(test_config, cached_config);
159 
160  config &child = test_config.add_child("test_key2");
161  child["define"] = t_string("testing translation reset.", GETTEXT_DOMAIN);
162 
163 
164  test_scoped_define test_define_def("TEST_DEFINE");
165  cached_config.clear();
166  cache.get_config(test_data_path, cached_config);
167  BOOST_CHECK_EQUAL(test_config, cached_config);
168 
169  BOOST_CHECK_EQUAL(test_config.mandatory_child("test_key2")["define"].str(), cached_config.mandatory_child("test_key2")["define"].str());
170 }
171 
172 BOOST_AUTO_TEST_CASE( test_non_clean_config_loading )
173 {
174 
175  config test_config = setup_test_config();
176 
177  // Test clean load first
178  {
179  config cfg;
180  cache.get_config(test_data_path, cfg);
181  BOOST_CHECK_EQUAL(test_config, cfg);
182  }
183 
184  // test non-clean one then
185  {
186  config cfg;
187  config &child = cfg.add_child("junk_data");
188  child["some_junk"] = "hah";
189  cache.get_config(test_data_path, cfg);
190  BOOST_CHECK_EQUAL(test_config, cfg);
191  }
192 }
193 
194 BOOST_AUTO_TEST_CASE( test_macrosubstitution )
195 {
196  config test_config = setup_test_config();
197 
198  config &child = test_config.add_child("test_key3");
199  child["define"] = "transaction";
200  config &child2 = test_config.add_child("test_key4");
201  child2["defined"] = "parameter";
202 
203  // test first that macro loading works
204  test_scoped_define macro("TEST_MACRO");
205 
206  // Without cache
207  config cached_config;
208  cache.get_config(test_data_path, cached_config);
209  BOOST_CHECK_EQUAL(test_config, cached_config);
210 
211  // With cache
212  cached_config.clear();
213  cache.get_config(test_data_path, cached_config);
214  BOOST_CHECK_EQUAL(test_config, cached_config);
215 
216 
217 }
218 
219 BOOST_AUTO_TEST_CASE( test_transaction )
220 {
221  config test_config = setup_test_config();
222 
223  config* child = &test_config.add_child("test_key3");
224  (*child)["define"] = "transaction";
225  child = &test_config.add_child("test_key4");
226  (*child)["defined"] = "parameter";
227 
228  // test first that macro loading works
229  test_scoped_define macro("TEST_MACRO");
230 
231  //Start transaction
232 
234 
235  config cached_config;
236  cache.get_config(test_data_path, cached_config);
237  BOOST_CHECK_EQUAL(test_config, cached_config);
238 
239  transaction.lock();
240  config umc_config;
241  child = &umc_config.add_child("umc");
242  (*child)["test"] = "umc load";
243  child = &umc_config.add_child("test_key3");
244  (*child)["define"] = "transaction";
245  child = &umc_config.add_child("test_key4");
246  (*child)["defined"] = "parameter";
247  cached_config.clear();
248  cache.get_config("data/test/test/umc.cfg", cached_config);
249  BOOST_CHECK_EQUAL(umc_config, cached_config);
250 }
251 
252 BOOST_AUTO_TEST_CASE( test_define_loading )
253 {
254  // try to load umc without valid cache
255  config test_config = setup_test_config();
256 
257  config* child = &test_config.add_child("test_key3");
258  (*child)["define"] = "transaction";
259  child = &test_config.add_child("test_key4");
260  (*child)["defined"] = "parameter";
261 
262  // test first that macro loading works
263  test_scoped_define macro("TEST_MACRO");
264 
265  //Start transaction
266 
268 
269  config cached_config;
270  cache.get_config(test_data_path, cached_config);
271  BOOST_CHECK_EQUAL(test_config, cached_config);
272 
273  transaction.lock();
274 
275  cache.set_force_invalid_cache(true);
276  config umc_config;
277  child = &umc_config.add_child("umc");
278  (*child)["test"] = "umc load";
279  child = &umc_config.add_child("test_key3");
280  (*child)["define"] = "transaction";
281  child = &umc_config.add_child("test_key4");
282  (*child)["defined"] = "parameter";
283  cached_config.clear();
284  cache.get_config("data/test/test/umc.cfg", cached_config);
285  BOOST_CHECK_EQUAL(umc_config, cached_config);
286  cache.set_force_invalid_cache(false);
287 }
288 
289 BOOST_AUTO_TEST_CASE( test_lead_spaces_loading )
290 {
291  config test_config;
292  test_config.add_child("test_lead_space")["space"] = "empty char in middle";
293  // Force reload of cache
294  cache.set_force_invalid_cache(true);
295  config cached_config;
296  cache.get_config("data/test/test/leading_space.cfg", cached_config);
297  BOOST_CHECK_EQUAL(test_config, cached_config);
298  cache.set_force_invalid_cache(false);
299  cached_config.clear();
300  cache.get_config("data/test/test/leading_space.cfg", cached_config);
301  BOOST_CHECK_EQUAL(test_config, cached_config);
302 }
303 
304 #if 0
305 // for profiling cache speed
306 BOOST_AUTO_TEST_CASE( test_performance )
307 {
308  test_scoped_define mp("MULTIPLAYER");
309  config cfg_ref;
310 // cache.set_force_invalid_cache(true);
311  cache.get_config("data/", cfg_ref);
312 // cache.set_force_invalid_cache(false);
313  for (int i=0; i < 3; ++i)
314  {
315  cache.get_config("data/");
316  }
317 }
318 #endif
319 
320 /* vim: set ts=4 sw=4: */
321 BOOST_AUTO_TEST_SUITE_END()
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:172
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
Definition: config.cpp:366
void clear()
Definition: config.cpp:828
config & add_child(config_key_type key)
Definition: config.cpp:440
Used to share macros between cache objects You have to create transaction object to load all macros t...
void lock()
Lock the transaction so no more macros are added.
Singleton class to manage game config file caching.
void add_define(const std::string &define)
Add a entry to preproc defines map.
const preproc_map & get_preproc_map() const
void remove_define(const std::string &define)
Remove a entry to preproc defines map.
Used to make distinct singleton for testing it because other tests will need original one to load dat...
static test_config_cache & instance()
void set_force_invalid_cache(bool force)
Definitions for the interface to Wesnoth Markup Language (WML).
std::size_t i
Definition: function.cpp:1028
Interfaces for manipulating version numbers of engine, add-ons, etc.
const language_def & get_language()
Definition: language.cpp:325
Standard logging facilities (interface).
Game configuration data as global variables.
Definition: build_info.cpp:61
const version_info wesnoth_version(VERSION)
Main entry points of multiplayer mode.
Definition: lobby_data.cpp:50
const config & get_test_config_ref()
void set_language(const std::string &language, const std::vector< std::string > *)
Definition: gettext.cpp:494
std::string_view data
Definition: picture.cpp:178
std::map< std::string, struct preproc_define > preproc_map
test_config_cache & cache
test_scoped_define test_def
static config setup_test_config()
static preproc_map setup_test_preproc_map()
BOOST_AUTO_TEST_CASE(test_preproc_defines)
#define GETTEXT_DOMAIN
const std::string test_data_path("data/test/test/_main.cfg")
game_config::scoped_preproc_define_internal< test_config_cache > test_scoped_define
Used to redirect defines settings to test cache.
BOOST_FIXTURE_TEST_SUITE(test_map_location, MLFixture)