The Battle for Wesnoth  1.15.2+dev
test_config_cache.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2018 by Pauli Nieminen <paniemin@cc.hut.fi>
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include <boost/test/unit_test.hpp>
16 
17 #define GETTEXT_DOMAIN "wesnoth-test"
18 
19 
20 #include "config_cache.hpp"
21 #include "config.hpp"
22 #include "game_config.hpp"
23 #include "language.hpp"
24 #include "game_version.hpp"
25 
27 
28 #include "utils/functional.hpp"
29 
30 
32 {
33  preproc_map defines_map;
34 
35 #if defined(__APPLE__)
36  defines_map["APPLE"] = preproc_define();
37 #endif
38 
39  defines_map["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
40 
41  return defines_map;
42 
43 }
44 
45 
46 /**
47  * Used to make distinct singleton for testing it
48  * because other tests will need original one to load data
49  **/
52 
53  public:
54  static test_config_cache& instance() ;
55 
56  void set_force_invalid_cache(bool force)
57  {
59  }
60 };
61 
63  static test_config_cache * cache_ = new test_config_cache;
64  return *cache_;
65 }
66 
67 /**
68  * Used to redirect defines settings to test cache
69  **/
71 
73  config_cache_fixture() : cache(test_config_cache::instance()), old_locale(get_language()), test_def("TEST")
74  {
76  }
78  {
79  set_language(old_locale);
80  }
84 };
85 
86 BOOST_AUTO_TEST_CASE( test_preproc_defines )
87 {
89  const preproc_map& test_defines = cache.get_preproc_map();
90  preproc_map defines_map(setup_test_preproc_map());
91 
92  // check initial state
93  BOOST_REQUIRE_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
94  defines_map.begin() ,defines_map.end());
95 
96  // scoped
97  {
98  test_scoped_define test("TEST");
99  defines_map["TEST"] = preproc_define();
100 
101  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
102  defines_map.begin() ,defines_map.end());
103  defines_map.erase("TEST");
104  }
105  // Check scoped remove
106 
107  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
108  defines_map.begin() ,defines_map.end());
109 
110  // Manual add define
111  cache.add_define("TEST");
112  defines_map["TEST"] = preproc_define();
113  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
114  defines_map.begin() ,defines_map.end());
115 
116  // Manual remove define
117  cache.remove_define("TEST");
118  defines_map.erase("TEST");
119  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
120  defines_map.begin() ,defines_map.end());
121 }
122 
123 BOOST_AUTO_TEST_CASE( test_config_cache_defaults )
124 {
126  preproc_map defines_map(setup_test_preproc_map());
127 
128  const preproc_map& test_defines = cache.get_preproc_map();
129  BOOST_CHECK_EQUAL_COLLECTIONS(test_defines.begin(),test_defines.end(),
130  defines_map.begin() ,defines_map.end());
131 }
132 
133 
134 BOOST_FIXTURE_TEST_SUITE( config_cache, config_cache_fixture )
135 
136  const std::string test_data_path("data/test/test/_main.cfg");
137 
139 {
140  config test_config;
141  config* child = &test_config.add_child("textdomain");
142  (*child)["name"] = GETTEXT_DOMAIN;
143 
144  child = &test_config.add_child("test_key");
145  (*child)["define"] = "test";
146  return test_config;
147 }
148 
149 
150 BOOST_AUTO_TEST_CASE( test_load_config )
151 {
152 
153  config test_config = setup_test_config();
154  config cached_config;
155  cache.get_config(test_data_path, cached_config);
156  BOOST_CHECK_EQUAL(test_config, cached_config);
157 
158  config &child = test_config.add_child("test_key2");
159  child["define"] = t_string("testing translation reset.", GETTEXT_DOMAIN);
160 
161 
162  test_scoped_define test_define_def("TEST_DEFINE");
163  cached_config.clear();
164  cache.get_config(test_data_path, cached_config);
165  BOOST_CHECK_EQUAL(test_config, cached_config);
166 
167  BOOST_CHECK_EQUAL(test_config.child("test_key2")["define"].str(), cached_config.child("test_key2")["define"].str());
168 }
169 
170 BOOST_AUTO_TEST_CASE( test_non_clean_config_loading )
171 {
172 
173  config test_config = setup_test_config();
174 
175  // Test clean load first
176  {
177  config cfg;
178  cache.get_config(test_data_path, cfg);
179  BOOST_CHECK_EQUAL(test_config, cfg);
180  }
181 
182  // test non-clean one then
183  {
184  config cfg;
185  config &child = cfg.add_child("junk_data");
186  child["some_junk"] = "hah";
187  cache.get_config(test_data_path, cfg);
188  BOOST_CHECK_EQUAL(test_config, cfg);
189  }
190 }
191 
192 BOOST_AUTO_TEST_CASE( test_macrosubstitution )
193 {
194  config test_config = setup_test_config();
195 
196  config &child = test_config.add_child("test_key3");
197  child["define"] = "transaction";
198  config &child2 = test_config.add_child("test_key4");
199  child2["defined"] = "parameter";
200 
201  // test first that macro loading works
202  test_scoped_define macro("TEST_MACRO");
203 
204  // Without cache
205  config cached_config;
206  cache.get_config(test_data_path, cached_config);
207  BOOST_CHECK_EQUAL(test_config, cached_config);
208 
209  // With cache
210  cached_config.clear();
211  cache.get_config(test_data_path, cached_config);
212  BOOST_CHECK_EQUAL(test_config, cached_config);
213 
214 
215 }
216 
217 BOOST_AUTO_TEST_CASE( test_transaction )
218 {
219  config test_config = setup_test_config();
220 
221  config* child = &test_config.add_child("test_key3");
222  (*child)["define"] = "transaction";
223  child = &test_config.add_child("test_key4");
224  (*child)["defined"] = "parameter";
225 
226  // test first that macro loading works
227  test_scoped_define macro("TEST_MACRO");
228 
229  //Start transaction
230 
232 
233  config cached_config;
234  cache.get_config(test_data_path, cached_config);
235  BOOST_CHECK_EQUAL(test_config, cached_config);
236 
237  transaction.lock();
238  config umc_config;
239  child = &umc_config.add_child("umc");
240  (*child)["test"] = "umc load";
241  child = &umc_config.add_child("test_key3");
242  (*child)["define"] = "transaction";
243  child = &umc_config.add_child("test_key4");
244  (*child)["defined"] = "parameter";
245  cached_config.clear();
246  cache.get_config("data/test/test/umc.cfg", cached_config);
247  BOOST_CHECK_EQUAL(umc_config, cached_config);
248 }
249 
250 BOOST_AUTO_TEST_CASE( test_define_loading )
251 {
252  // try to load umc without valid cache
253  config test_config = setup_test_config();
254 
255  config* child = &test_config.add_child("test_key3");
256  (*child)["define"] = "transaction";
257  child = &test_config.add_child("test_key4");
258  (*child)["defined"] = "parameter";
259 
260  // test first that macro loading works
261  test_scoped_define macro("TEST_MACRO");
262 
263  //Start transaction
264 
266 
267  config cached_config;
268  cache.get_config(test_data_path, cached_config);
269  BOOST_CHECK_EQUAL(test_config, cached_config);
270 
271  transaction.lock();
272 
273  cache.set_force_invalid_cache(true);
274  config umc_config;
275  child = &umc_config.add_child("umc");
276  (*child)["test"] = "umc load";
277  child = &umc_config.add_child("test_key3");
278  (*child)["define"] = "transaction";
279  child = &umc_config.add_child("test_key4");
280  (*child)["defined"] = "parameter";
281  cached_config.clear();
282  cache.get_config("data/test/test/umc.cfg", cached_config);
283  BOOST_CHECK_EQUAL(umc_config, cached_config);
284  cache.set_force_invalid_cache(false);
285 }
286 
287 BOOST_AUTO_TEST_CASE( test_lead_spaces_loading )
288 {
289  config test_config;
290  test_config.add_child("test_lead_space")["space"] = "empty char in middle";
291  // Force reload of cache
292  cache.set_force_invalid_cache(true);
293  config cached_config;
294  cache.get_config("data/test/test/leading_space.cfg", cached_config);
295  BOOST_CHECK_EQUAL(test_config, cached_config);
296  cache.set_force_invalid_cache(false);
297  cached_config.clear();
298  cache.get_config("data/test/test/leading_space.cfg", cached_config);
299  BOOST_CHECK_EQUAL(test_config, cached_config);
300 }
301 
302 #if 0
303 // for profiling cache speed
304 BOOST_AUTO_TEST_CASE( test_performance )
305 {
306  test_scoped_define mp("MULTIPLAYER");
307  config cfg_ref;
308 // cache.set_force_invalid_cache(true);
309  cache.get_config("data/", cfg_ref);
310 // cache.set_force_invalid_cache(false);
311  for (int i=0; i < 3; ++i)
312  {
313  cache.get_config("data/");
314  }
315 }
316 #endif
317 
318 /* vim: set ts=4 sw=4: */
319 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:420
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:449
void remove_define(const std::string &define)
Remove a entry to preproc defines map.
void clear()
Definition: config.cpp:863
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
Pubic entry points for the MP workflow.
Definition: lobby_data.cpp:50
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:933
Game configuration data as global variables.
Definition: build_info.cpp:49
const preproc_map & get_preproc_map() const
const language_def & get_language()
Definition: language.cpp:261
static tcache cache
Definition: minimap.cpp:134
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:476
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:68
void add_define(const std::string &define)
Add a entry to preproc defines map.
Singleton class to manage game config file caching.