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