The Battle for Wesnoth  1.17.0-dev
test_config_cache.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2021
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  defines_map["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
41 
42  return defines_map;
43 
44 }
45 
46 
47 /**
48  * Used to make distinct singleton for testing it
49  * because other tests will need original one to load data
50  **/
53 
54  public:
55  static test_config_cache& instance() ;
56 
57  void set_force_invalid_cache(bool force)
58  {
60  }
61 };
62 
64  static test_config_cache * cache_ = new test_config_cache;
65  return *cache_;
66 }
67 
68 /**
69  * Used to redirect defines settings to test cache
70  **/
72 
74  config_cache_fixture() : cache(test_config_cache::instance()), old_locale(get_language()), test_def("TEST")
75  {
77  }
79  {
80  set_language(old_locale);
81  }
85 };
86 
87 BOOST_AUTO_TEST_CASE( test_preproc_defines )
88 {
90  const preproc_map& test_defines = cache.get_preproc_map();
91  preproc_map defines_map(setup_test_preproc_map());
92 
93  // check initial state
94  BOOST_REQUIRE_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
95  defines_map.begin() ,defines_map.end());
96 
97  // scoped
98  {
99  test_scoped_define test("TEST");
100  defines_map["TEST"] = preproc_define();
101 
102  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
103  defines_map.begin() ,defines_map.end());
104  defines_map.erase("TEST");
105  }
106  // Check scoped remove
107 
108  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
109  defines_map.begin() ,defines_map.end());
110 
111  // Manual add define
112  cache.add_define("TEST");
113  defines_map["TEST"] = preproc_define();
114  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
115  defines_map.begin() ,defines_map.end());
116 
117  // Manual remove define
118  cache.remove_define("TEST");
119  defines_map.erase("TEST");
120  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
121  defines_map.begin() ,defines_map.end());
122 }
123 
124 BOOST_AUTO_TEST_CASE( test_config_cache_defaults )
125 {
127  preproc_map defines_map(setup_test_preproc_map());
128 
129  const preproc_map& test_defines = cache.get_preproc_map();
130  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
131  defines_map.begin() ,defines_map.end());
132 }
133 
134 
135 BOOST_FIXTURE_TEST_SUITE( config_cache, config_cache_fixture )
136 
137  const std::string test_data_path("data/test/test/_main.cfg");
138 
140 {
141  config test_config;
142  config* child = &test_config.add_child("textdomain");
143  (*child)["name"] = GETTEXT_DOMAIN;
144 
145  child = &test_config.add_child("test_key");
146  (*child)["define"] = "test";
147  return test_config;
148 }
149 
150 
151 BOOST_AUTO_TEST_CASE( test_load_config )
152 {
153 
154  config test_config = setup_test_config();
155  config cached_config;
156  cache.get_config(test_data_path, cached_config);
157  BOOST_CHECK_EQUAL(test_config, cached_config);
158 
159  config &child = test_config.add_child("test_key2");
160  child["define"] = t_string("testing translation reset.", GETTEXT_DOMAIN);
161 
162 
163  test_scoped_define test_define_def("TEST_DEFINE");
164  cached_config.clear();
165  cache.get_config(test_data_path, cached_config);
166  BOOST_CHECK_EQUAL(test_config, cached_config);
167 
168  BOOST_CHECK_EQUAL(test_config.child("test_key2")["define"].str(), cached_config.child("test_key2")["define"].str());
169 }
170 
171 BOOST_AUTO_TEST_CASE( test_non_clean_config_loading )
172 {
173 
174  config test_config = setup_test_config();
175 
176  // Test clean load first
177  {
178  config cfg;
179  cache.get_config(test_data_path, cfg);
180  BOOST_CHECK_EQUAL(test_config, cfg);
181  }
182 
183  // test non-clean one then
184  {
185  config cfg;
186  config &child = cfg.add_child("junk_data");
187  child["some_junk"] = "hah";
188  cache.get_config(test_data_path, cfg);
189  BOOST_CHECK_EQUAL(test_config, cfg);
190  }
191 }
192 
193 BOOST_AUTO_TEST_CASE( test_macrosubstitution )
194 {
195  config test_config = setup_test_config();
196 
197  config &child = test_config.add_child("test_key3");
198  child["define"] = "transaction";
199  config &child2 = test_config.add_child("test_key4");
200  child2["defined"] = "parameter";
201 
202  // test first that macro loading works
203  test_scoped_define macro("TEST_MACRO");
204 
205  // Without cache
206  config cached_config;
207  cache.get_config(test_data_path, cached_config);
208  BOOST_CHECK_EQUAL(test_config, cached_config);
209 
210  // With cache
211  cached_config.clear();
212  cache.get_config(test_data_path, cached_config);
213  BOOST_CHECK_EQUAL(test_config, cached_config);
214 
215 
216 }
217 
218 BOOST_AUTO_TEST_CASE( test_transaction )
219 {
220  config test_config = setup_test_config();
221 
222  config* child = &test_config.add_child("test_key3");
223  (*child)["define"] = "transaction";
224  child = &test_config.add_child("test_key4");
225  (*child)["defined"] = "parameter";
226 
227  // test first that macro loading works
228  test_scoped_define macro("TEST_MACRO");
229 
230  //Start transaction
231 
233 
234  config cached_config;
235  cache.get_config(test_data_path, cached_config);
236  BOOST_CHECK_EQUAL(test_config, cached_config);
237 
238  transaction.lock();
239  config umc_config;
240  child = &umc_config.add_child("umc");
241  (*child)["test"] = "umc load";
242  child = &umc_config.add_child("test_key3");
243  (*child)["define"] = "transaction";
244  child = &umc_config.add_child("test_key4");
245  (*child)["defined"] = "parameter";
246  cached_config.clear();
247  cache.get_config("data/test/test/umc.cfg", cached_config);
248  BOOST_CHECK_EQUAL(umc_config, cached_config);
249 }
250 
251 BOOST_AUTO_TEST_CASE( test_define_loading )
252 {
253  // try to load umc without valid cache
254  config test_config = setup_test_config();
255 
256  config* child = &test_config.add_child("test_key3");
257  (*child)["define"] = "transaction";
258  child = &test_config.add_child("test_key4");
259  (*child)["defined"] = "parameter";
260 
261  // test first that macro loading works
262  test_scoped_define macro("TEST_MACRO");
263 
264  //Start transaction
265 
267 
268  config cached_config;
269  cache.get_config(test_data_path, cached_config);
270  BOOST_CHECK_EQUAL(test_config, cached_config);
271 
272  transaction.lock();
273 
274  cache.set_force_invalid_cache(true);
275  config umc_config;
276  child = &umc_config.add_child("umc");
277  (*child)["test"] = "umc load";
278  child = &umc_config.add_child("test_key3");
279  (*child)["define"] = "transaction";
280  child = &umc_config.add_child("test_key4");
281  (*child)["defined"] = "parameter";
282  cached_config.clear();
283  cache.get_config("data/test/test/umc.cfg", cached_config);
284  BOOST_CHECK_EQUAL(umc_config, cached_config);
285  cache.set_force_invalid_cache(false);
286 }
287 
288 BOOST_AUTO_TEST_CASE( test_lead_spaces_loading )
289 {
290  config test_config;
291  test_config.add_child("test_lead_space")["space"] = "empty char in middle";
292  // Force reload of cache
293  cache.set_force_invalid_cache(true);
294  config cached_config;
295  cache.get_config("data/test/test/leading_space.cfg", cached_config);
296  BOOST_CHECK_EQUAL(test_config, cached_config);
297  cache.set_force_invalid_cache(false);
298  cached_config.clear();
299  cache.get_config("data/test/test/leading_space.cfg", cached_config);
300  BOOST_CHECK_EQUAL(test_config, cached_config);
301 }
302 
303 #if 0
304 // for profiling cache speed
305 BOOST_AUTO_TEST_CASE( test_performance )
306 {
307  test_scoped_define mp("MULTIPLAYER");
308  config cfg_ref;
309 // cache.set_force_invalid_cache(true);
310  cache.get_config("data/", cfg_ref);
311 // cache.set_force_invalid_cache(false);
312  for (int i=0; i < 3; ++i)
313  {
314  cache.get_config("data/");
315  }
316 }
317 #endif
318 
319 /* vim: set ts=4 sw=4: */
320 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:489
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()
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:59
const preproc_map & get_preproc_map() const
const language_def & get_language()
Definition: language.cpp:327
static tcache cache
Definition: minimap.cpp:124
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:61
void add_define(const std::string &define)
Add a entry to preproc defines map.
Singleton class to manage game config file caching.