test_settings.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "test.h"
  17. #include <cmath>
  18. #include "settings.h"
  19. #include "defaultsettings.h"
  20. #include "noise.h"
  21. class TestSettings : public TestBase {
  22. public:
  23. TestSettings() { TestManager::registerTestModule(this); }
  24. const char *getName() { return "TestSettings"; }
  25. void runTests(IGameDef *gamedef);
  26. void testAllSettings();
  27. void testDefaults();
  28. void testFlagDesc();
  29. static const char *config_text_before;
  30. static const std::string config_text_after;
  31. };
  32. static TestSettings g_test_instance;
  33. void TestSettings::runTests(IGameDef *gamedef)
  34. {
  35. TEST(testAllSettings);
  36. TEST(testDefaults);
  37. TEST(testFlagDesc);
  38. }
  39. ////////////////////////////////////////////////////////////////////////////////
  40. const char *TestSettings::config_text_before =
  41. "leet = 1337\n"
  42. "leetleet = 13371337\n"
  43. "leetleet_neg = -13371337\n"
  44. "floaty_thing = 1.1\n"
  45. "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n"
  46. "coord = (1, 2, 4.5)\n"
  47. " # this is just a comment\n"
  48. "this is an invalid line\n"
  49. "asdf = {\n"
  50. " a = 5\n"
  51. " bb = 2.5\n"
  52. " ccc = \"\"\"\n"
  53. "testy\n"
  54. " testa \n"
  55. "\"\"\"\n"
  56. "\n"
  57. "}\n"
  58. "blarg = \"\"\" \n"
  59. "some multiline text\n"
  60. " with leading whitespace!\n"
  61. "\"\"\"\n"
  62. "np_terrain = 5, 40, (250, 250, 250), 12341, 5, 0.700012505, 2.40012503\n"
  63. "zoop = true\n"
  64. "[dummy_eof_end_tag]\n";
  65. const std::string TestSettings::config_text_after =
  66. "leet = 1337\n"
  67. "leetleet = 13371337\n"
  68. "leetleet_neg = -13371337\n"
  69. "floaty_thing = 1.1\n"
  70. "stringy_thing = asd /( ¤%&(/\" BLÖÄRP\n"
  71. "coord = (1, 2, 4.5)\n"
  72. " # this is just a comment\n"
  73. "this is an invalid line\n"
  74. "asdf = {\n"
  75. " a = 5\n"
  76. " bb = 2.5\n"
  77. " ccc = \"\"\"\n"
  78. "testy\n"
  79. " testa \n"
  80. "\"\"\"\n"
  81. "\n"
  82. "}\n"
  83. "blarg = \"\"\" \n"
  84. "some multiline text\n"
  85. " with leading whitespace!\n"
  86. "\"\"\"\n"
  87. "np_terrain = {\n"
  88. " flags = defaults\n"
  89. " lacunarity = 2.40012503\n"
  90. " octaves = 6\n"
  91. " offset = 3.5\n"
  92. " persistence = 0.700012505\n"
  93. " scale = 40\n"
  94. " seed = 12341\n"
  95. " spread = (250,250,250)\n"
  96. "}\n"
  97. "zoop = true\n"
  98. "coord2 = (1,2,3.3)\n"
  99. "floaty_thing_2 = 1.25\n"
  100. "groupy_thing = {\n"
  101. " animals = cute\n"
  102. " num_apples = 4\n"
  103. " num_oranges = 53\n"
  104. "}\n"
  105. "[dummy_eof_end_tag]";
  106. void compare_settings(const std::string &name, Settings *a, Settings *b)
  107. {
  108. auto keys = a->getNames();
  109. Settings *group1, *group2;
  110. std::string value1, value2;
  111. for (auto &key : keys) {
  112. if (a->getGroupNoEx(key, group1)) {
  113. UASSERT(b->getGroupNoEx(key, group2));
  114. compare_settings(name + "->" + key, group1, group2);
  115. continue;
  116. }
  117. UASSERT(b->getNoEx(key, value1));
  118. // For identification
  119. value1 = name + "->" + key + "=" + value1;
  120. value2 = name + "->" + key + "=" + a->get(key);
  121. UASSERTCMP(std::string, ==, value2, value1);
  122. }
  123. }
  124. void TestSettings::testAllSettings()
  125. {
  126. try {
  127. Settings s("[dummy_eof_end_tag]");
  128. // Test reading of settings
  129. std::istringstream is(config_text_before);
  130. s.parseConfigLines(is);
  131. UASSERT(s.getS32("leet") == 1337);
  132. UASSERT(s.getS16("leetleet") == 32767);
  133. UASSERT(s.getS16("leetleet_neg") == -32768);
  134. // Not sure if 1.1 is an exact value as a float, but doesn't matter
  135. UASSERT(fabs(s.getFloat("floaty_thing") - 1.1) < 0.001);
  136. UASSERT(s.get("stringy_thing") == "asd /( ¤%&(/\" BLÖÄRP");
  137. UASSERT(fabs(s.getV3F("coord").X - 1.0) < 0.001);
  138. UASSERT(fabs(s.getV3F("coord").Y - 2.0) < 0.001);
  139. UASSERT(fabs(s.getV3F("coord").Z - 4.5) < 0.001);
  140. // Test the setting of settings too
  141. s.setFloat("floaty_thing_2", 1.25);
  142. s.setV3F("coord2", v3f(1, 2, 3.3));
  143. UASSERT(s.get("floaty_thing_2").substr(0,4) == "1.25");
  144. UASSERT(fabs(s.getFloat("floaty_thing_2") - 1.25) < 0.001);
  145. UASSERT(fabs(s.getV3F("coord2").X - 1.0) < 0.001);
  146. UASSERT(fabs(s.getV3F("coord2").Y - 2.0) < 0.001);
  147. UASSERT(fabs(s.getV3F("coord2").Z - 3.3) < 0.001);
  148. // Test settings groups
  149. Settings *group = s.getGroup("asdf");
  150. UASSERT(group != NULL);
  151. UASSERT(s.getGroupNoEx("zoop", group) == false);
  152. UASSERT(group->getS16("a") == 5);
  153. UASSERT(fabs(group->getFloat("bb") - 2.5) < 0.001);
  154. Settings group3;
  155. group3.set("cat", "meow");
  156. group3.set("dog", "woof");
  157. Settings group2;
  158. group2.setS16("num_apples", 4);
  159. group2.setS16("num_oranges", 53);
  160. group2.setGroup("animals", group3);
  161. group2.set("animals", "cute"); //destroys group 3
  162. s.setGroup("groupy_thing", group2);
  163. // Test set failure conditions
  164. UASSERT(s.set("Zoop = Poop\nsome_other_setting", "false") == false);
  165. UASSERT(s.set("sneaky", "\"\"\"\njabberwocky = false") == false);
  166. UASSERT(s.set("hehe", "asdfasdf\n\"\"\"\nsomething = false") == false);
  167. // Test multiline settings
  168. UASSERT(group->get("ccc") == "testy\n testa ");
  169. UASSERT(s.get("blarg") ==
  170. "some multiline text\n"
  171. " with leading whitespace!");
  172. // Test NoiseParams
  173. UASSERT(s.getEntry("np_terrain").is_group == false);
  174. NoiseParams np;
  175. UASSERT(s.getNoiseParams("np_terrain", np) == true);
  176. UASSERT(std::fabs(np.offset - 5) < 0.001f);
  177. UASSERT(std::fabs(np.scale - 40) < 0.001f);
  178. UASSERT(std::fabs(np.spread.X - 250) < 0.001f);
  179. UASSERT(std::fabs(np.spread.Y - 250) < 0.001f);
  180. UASSERT(std::fabs(np.spread.Z - 250) < 0.001f);
  181. UASSERT(np.seed == 12341);
  182. UASSERT(np.octaves == 5);
  183. UASSERT(std::fabs(np.persist - 0.7) < 0.001f);
  184. np.offset = 3.5;
  185. np.octaves = 6;
  186. s.setNoiseParams("np_terrain", np);
  187. UASSERT(s.getEntry("np_terrain").is_group == true);
  188. // Test writing
  189. std::ostringstream os(std::ios_base::binary);
  190. is.clear();
  191. is.seekg(0);
  192. UASSERT(s.updateConfigObject(is, os, 0) == true);
  193. {
  194. // Confirm settings
  195. Settings s2("[dummy_eof_end_tag]");
  196. std::istringstream is(config_text_after, std::ios_base::binary);
  197. UASSERT(s2.parseConfigLines(is) == true);
  198. compare_settings("(main)", &s, &s2);
  199. }
  200. } catch (SettingNotFoundException &e) {
  201. UASSERT(!"Setting not found!");
  202. }
  203. }
  204. void TestSettings::testDefaults()
  205. {
  206. Settings *game = Settings::createLayer(SL_GAME);
  207. Settings *def = Settings::getLayer(SL_DEFAULTS);
  208. def->set("name", "FooBar");
  209. UASSERT(def->get("name") == "FooBar");
  210. UASSERT(game->get("name") == "FooBar");
  211. game->set("name", "Baz");
  212. UASSERT(game->get("name") == "Baz");
  213. delete game;
  214. // Restore default settings
  215. delete Settings::getLayer(SL_DEFAULTS);
  216. set_default_settings();
  217. }
  218. void TestSettings::testFlagDesc()
  219. {
  220. Settings &s = *Settings::createLayer(SL_GAME);
  221. FlagDesc flagdesc[] = {
  222. { "biomes", 0x01 },
  223. { "trees", 0x02 },
  224. { "jungles", 0x04 },
  225. { "oranges", 0x08 },
  226. { "tables", 0x10 },
  227. { nullptr, 0 }
  228. };
  229. // Enabled: biomes, jungles, oranges (default)
  230. s.setDefault("test_desc", flagdesc, readFlagString(
  231. "biomes,notrees,jungles,oranges", flagdesc, nullptr));
  232. UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x01 | 0x04 | 0x08));
  233. // Enabled: jungles, oranges, tables
  234. s.set("test_desc", "nobiomes,tables");
  235. UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == (0x04 | 0x08 | 0x10));
  236. // Enabled: (nothing)
  237. s.set("test_desc", "nobiomes,nojungles,nooranges,notables");
  238. UASSERT(s.getFlagStr("test_desc", flagdesc, nullptr) == 0x00);
  239. // Numeric flag tests (override)
  240. // Enabled: trees, tables
  241. s.setDefault("test_flags", flagdesc, 0x02 | 0x10);
  242. UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == (0x02 | 0x10));
  243. // Enabled: tables
  244. s.set("test_flags", "16");
  245. UASSERT(s.getFlagStr("test_flags", flagdesc, nullptr) == 0x10);
  246. delete &s;
  247. }