The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_config.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2016 by Chris Beck <[email protected]>
3  Part of the Battle for Wesnoth Project http://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 #define GETTEXT_DOMAIN "wesnoth-test"
16 
17 #include <boost/test/unit_test.hpp>
18 #include <cmath>
19 
20 #include "config.hpp"
21 #include "config_assign.hpp"
22 #include "variable_info.hpp"
23 
24 BOOST_AUTO_TEST_SUITE ( test_config )
25 
26 BOOST_AUTO_TEST_CASE ( test_config_attribute_value )
27 {
28  config c;
29  const config& cc = c;
30  int x_int;
31  std::string x_str;
32  long long x_sll;
33  double x_dbl;
34 
35  c["x"] = 1;
36  x_str = c["x"].str();
37  BOOST_CHECK_EQUAL(x_str, "1");
38  x_int = c["x"].to_int();
39  BOOST_CHECK_EQUAL(x_int, 1);
40  x_sll = c["x"].to_long_long();
41  BOOST_CHECK_EQUAL(x_sll, 1ll);
42  x_dbl = c["x"].to_double();
43  BOOST_CHECK_EQUAL(x_dbl, 1.0);
44 
45 
46  c["x"] = 10000000;
47  x_int = c["x"].to_int();
48  BOOST_CHECK_EQUAL(x_int, 10000000);
49  x_str = c["x"].str();
50  BOOST_CHECK_EQUAL(x_str, "10000000");
51  x_sll = c["x"].to_long_long();
52  BOOST_CHECK_EQUAL(x_sll, 10000000ll);
53  x_dbl = c["x"].to_double();
54  BOOST_CHECK_EQUAL(x_dbl, 1e7);
55 
56  c["x"] = "";
57  x_sll = c["x"].to_long_long();
58  BOOST_CHECK_EQUAL(x_sll, 0ll);
59  x_str = c["x"].str();
60  BOOST_CHECK_EQUAL(x_str, "");
61  x_int = c["x"].to_int();
62  BOOST_CHECK_EQUAL(x_int, 0);
63  x_dbl = c["x"].to_double();
64  BOOST_CHECK_EQUAL(x_dbl, 0.0);
65 
66 
67  c["x"] = "0x11";
68  x_int = c["x"].to_int();
69  BOOST_CHECK_EQUAL(x_int, 0);
70  x_str = c["x"].str();
71  BOOST_CHECK_EQUAL(x_str, "0x11");
72  x_sll = c["x"].to_long_long();
73  BOOST_CHECK_EQUAL(x_sll, 0ll);
74  x_dbl = c["x"].to_double();
75  BOOST_CHECK_EQUAL(x_dbl, 0.0);
76 
77 
78  c["x"] = "0xab";
79  x_int = c["x"].to_int();
80  BOOST_CHECK_EQUAL(x_int, 0);
81  x_str = c["x"].str();
82  BOOST_CHECK_EQUAL(x_str, "0xab");
83  x_sll = c["x"].to_long_long();
84  BOOST_CHECK_EQUAL(x_sll, 0ll);
85  x_dbl = c["x"].to_double();
86  BOOST_CHECK_EQUAL(x_dbl, 0.0);
87 
88 
89  c["x"] = "00001111";
90  x_int = c["x"].to_int();
91  BOOST_CHECK_EQUAL(x_int, 1111);
92  x_str = c["x"].str();
93  BOOST_CHECK_EQUAL(x_str, "00001111");
94  x_sll = c["x"].to_long_long();
95  BOOST_CHECK_EQUAL(x_sll, 1111ll);
96  x_dbl = c["x"].to_double();
97  BOOST_CHECK_EQUAL(x_dbl, 1.111e3);
98 
99 
100  c["x"] = "000000";
101  x_int = c["x"].to_int();
102  BOOST_CHECK_EQUAL(x_int, 0);
103  x_str = c["x"].str();
104  BOOST_CHECK_EQUAL(x_str,"000000");
105  x_sll = c["x"].to_long_long();
106  BOOST_CHECK_EQUAL(x_sll, 0ll);
107  x_dbl = c["x"].to_double();
108  BOOST_CHECK_EQUAL(x_dbl, 0.0);
109 
110 
111  c["x"] = "01234567890123456789";
112  x_sll = c["x"].to_long_long();
113  BOOST_CHECK_EQUAL(x_sll,1234567890123456789ll);
114  x_str = c["x"].str();
115  BOOST_CHECK_EQUAL(x_str,"01234567890123456789");
116  x_int = c["x"].to_int();
117  BOOST_CHECK_EQUAL(x_int, 0);
118  x_dbl = c["x"].to_double();
119  BOOST_CHECK_EQUAL(x_dbl, 1.23456789012345678e18);
120 
121 
122  c["x"] = "99999999999999999999";
123  x_sll = c["x"].to_long_long();
124  BOOST_CHECK_EQUAL(x_sll, 0ll);
125  x_str = c["x"].str();
126  BOOST_CHECK_EQUAL(x_str, "99999999999999999999");
127  x_int = c["x"].to_int();
128  BOOST_CHECK_EQUAL(x_int, 0);
129  x_dbl = c["x"].to_double();
130  BOOST_CHECK_EQUAL(x_dbl, 1e20);
131 
132  c["x"] = 1.499;
133  x_sll = c["x"].to_long_long();
134  BOOST_CHECK_EQUAL(x_sll, 1ll);
135  x_str = c["x"].str();
136  BOOST_CHECK_EQUAL(x_str, "1.499");
137  x_int = c["x"].to_int();
138  BOOST_CHECK_EQUAL(x_int, 1);
139  x_dbl = c["x"].to_double();
140  BOOST_CHECK(std::abs(x_dbl - 1.499) < 1e-6);
141 
142 
143  c["x"] = 123456789123ll;
144  x_int = c["x"].to_int();
145  BOOST_CHECK_EQUAL(x_int, -1097262461);
146  x_dbl = c["x"].to_double();
147  BOOST_CHECK_EQUAL(x_dbl, 1.23456789123e11);
148  x_sll = c["x"].to_long_long();
149  BOOST_CHECK_EQUAL(x_sll, 123456789123ll);
150  x_str = c["x"].str();
151  BOOST_CHECK_EQUAL(x_str, "123456789123");
152 
153  // blank != "" test.
154  c = config();
155  BOOST_CHECK(cc["x"] != "");
156  BOOST_CHECK(cc["x"].empty());
157  BOOST_CHECK(cc["x"].blank());
158 
159  BOOST_CHECK(c["x"] != "");
160  BOOST_CHECK(c["x"].empty());
161  BOOST_CHECK(c["x"].blank());
162 
163  BOOST_CHECK_EQUAL(cc["x"], c["x"]);
164 
165  c["x"] = "";
166  BOOST_CHECK(cc["x"] == "");
167  BOOST_CHECK(cc["x"].empty());
168  BOOST_CHECK(!cc["x"].blank());
169 
170  BOOST_CHECK(c["x"] == "");
171  BOOST_CHECK(c["x"].empty());
172  BOOST_CHECK(!c["x"].blank());
173 
174  BOOST_CHECK_EQUAL(cc["x"], c["x"]);
175 }
176 
177 BOOST_AUTO_TEST_CASE ( test_variable_info )
178 {
179  config c;
180  {
182  // We dotn allow empty keys
183  BOOST_CHECK_THROW (access.as_scalar(), invalid_variablename_exception);
184  }
185  {
186  variable_access_const access("some_non_existent.", c);
187  // We dotn allow empty keys
188  BOOST_CHECK_THROW (access.as_scalar(), invalid_variablename_exception);
189  }
190  {
191  variable_access_const access("some_non_existent[0]value", c);
192  // We expect '.' after ']'
193  BOOST_CHECK_THROW (access.as_scalar(), invalid_variablename_exception);
194  }
195  {
196  variable_access_const access("some_non_existent", c);
197  // we return empty be default
198  BOOST_CHECK (!access.exists_as_container());
199  BOOST_CHECK_EQUAL (access.as_container(), config());
200  BOOST_CHECK (!access.exists_as_attribute());
201  BOOST_CHECK_EQUAL (access.as_scalar(), config::attribute_value());
202  }
203  {
204  variable_access_const access("a.b[0].c[1].d.e.f[2]", c);
205  // we return empty be default
206  BOOST_CHECK (!access.exists_as_container());
207  BOOST_CHECK_EQUAL (access.as_container(), config());
208  // Explicit indexes can never be an attribute
209  BOOST_CHECK_THROW (access.as_scalar(), invalid_variablename_exception);
210  }
211  BOOST_CHECK (c.empty());
212  {
213  config c2;
214  variable_access_create access("a.b[0].c[1].d.e.f[2].g", c2);
215  access.as_scalar() = 84;
216  BOOST_CHECK_EQUAL (variable_access_const("a.length", c2).as_scalar(), 1);
217  BOOST_CHECK_EQUAL (variable_access_const("a.b.length", c2).as_scalar(), 1);
218  BOOST_CHECK_EQUAL (variable_access_const("a.b.c.length", c2).as_scalar(), 2);
219  BOOST_CHECK_EQUAL (variable_access_const("a.b.c[1].d.e.f.length", c2).as_scalar(), 3);
220  // we setted g as a scalar
221  BOOST_CHECK_EQUAL (variable_access_const("a.b.c[1].d.e.f[2].g.length", c2).as_scalar(), 0);
222  BOOST_CHECK_EQUAL (variable_access_const("a.b.c[1].d.e.f[2].g", c2).as_scalar(), 84);
223  }
224  {
225  config c2;
226  variable_access_throw access("a.b[9].c", c2);
227  BOOST_CHECK_THROW(access.as_scalar(), invalid_variablename_exception);
228  }
229  {
230  const config nonempty = config_of
231  ("tag1", config())
232  ("tag1", config_of
233  ("tag2", config())
234  ("tag2", config())
235  ("tag2", config_of
236  ("atribute1", 88)
237  ("atribute2", "value")
238  )
239  )
240  ("tag1", config());
241  /** This is the config:
242  [tag1]
243  [/tag1]
244  [tag1]
245  [tag2]
246  [/tag2]
247  [tag2]
248  [/tag2]
249  [tag2]
250  atribute1 = 88
251  atribute2 = "value"
252  [/tag2]
253  [/tag1]
254  [tag1]
255  [/tag1]
256  */
257  BOOST_CHECK_EQUAL (variable_access_const("tag1.length", nonempty).as_scalar(), 3);
258  BOOST_CHECK_EQUAL (variable_access_const("tag1.tag2.length", nonempty).as_scalar(), 0);
259  BOOST_CHECK_EQUAL (variable_access_const("tag1[1].tag2.length", nonempty).as_scalar(), 3);
260  BOOST_CHECK_EQUAL (variable_access_const("tag1[1].tag2[2].atribute1", nonempty).as_scalar().to_int(), 88);
261  int count = 0;
262  for(const config& child : variable_access_const("tag1", nonempty).as_array())
263  {
264  //silences unused variable warning.
265  UNUSED(child);
266  ++count;
267  }
268  BOOST_CHECK_EQUAL (count, 3);
269  count = 0;
270  for(const config& child : variable_access_const("tag1.tag2", nonempty).as_array())
271  {
272  //silences unused variable warning.
273  UNUSED(child);
274  ++count;
275  }
276  BOOST_CHECK_EQUAL (count, 0);
277  count = 0;
278  // explicit indexes as range always return a one element range, whether they exist or not.
279  for(const config& child : variable_access_const("tag1.tag2[5]", nonempty).as_array())
280  {
281  //silences unused variable warning.
282  UNUSED(child);
283  ++count;
284  }
285  BOOST_CHECK_EQUAL (count, 1);
286  }
287 }
288 
289 BOOST_AUTO_TEST_SUITE_END()
variable_info_detail::maybe_const< vit, config::attribute_value >::type & as_scalar() const
might throw invalid_variablename_exception NOTE: If vit == vit_const, then the lifime of the returned...
bool exists_as_container() const
might throw invalid_variablename_exception
BOOST_AUTO_TEST_CASE(test_config_attribute_value)
Definition: test_config.cpp:26
variable_info< variable_info_detail::vit_const > variable_access_const
this variable accessor is takes a const reference and is guaranteed to not change the config...
Extends variable_info with methods that can only be applied if vit != vit_const.
BOOST_AUTO_TEST_SUITE(test_map_location)
bool empty() const
Definition: config.cpp:1105
Definitions for the interface to Wesnoth Markup Language (WML).
Variant for storing WML attributes.
Definition: config.hpp:223
GLuint GLuint GLsizei count
Definition: glew.h:1221
#define UNUSED(x)
Definition: global.hpp:56
GLuint GLint GLboolean GLint GLenum access
Definition: glew.h:8305
variable_info_detail::maybe_const< vit, config >::type & as_container() const
might throw invalid_variablename_exception
Information on a WML variable.
#define c
Definition: glew.h:12743
#define e
bool exists_as_attribute() const
might throw invalid_variablename_exception
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:83
GLsizei const GLcharARB ** string
Definition: glew.h:4503