3 Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "mapgen/mg_schematic.h"
26 class TestSchematic : public TestBase {
28 TestSchematic() { TestManager::registerTestModule(this); }
29 const char *getName() { return "TestSchematic"; }
31 void runTests(IGameDef *gamedef);
33 void testMtsSerializeDeserialize(const NodeDefManager *ndef);
34 void testLuaTableSerialize(const NodeDefManager *ndef);
35 void testFileSerializeDeserialize(const NodeDefManager *ndef);
37 static const content_t test_schem1_data[7 * 6 * 4];
38 static const content_t test_schem2_data[3 * 3 * 3];
39 static const u8 test_schem2_prob[3 * 3 * 3];
40 static const char *expected_lua_output;
43 static TestSchematic g_test_instance;
45 void TestSchematic::runTests(IGameDef *gamedef)
47 NodeDefManager *ndef =
48 (NodeDefManager *)gamedef->getNodeDefManager();
50 ndef->setNodeRegistrationStatus(true);
52 TEST(testMtsSerializeDeserialize, ndef);
53 TEST(testLuaTableSerialize, ndef);
54 TEST(testFileSerializeDeserialize, ndef);
56 ndef->resetNodeResolveState();
59 ////////////////////////////////////////////////////////////////////////////////
61 void TestSchematic::testMtsSerializeDeserialize(const NodeDefManager *ndef)
63 static const v3s16 size(7, 6, 4);
64 static const u32 volume = size.X * size.Y * size.Z;
66 std::stringstream ss(std::ios_base::binary |
67 std::ios_base::in | std::ios_base::out);
71 std::vector<std::string> &names = schem.m_nodenames;
72 names.emplace_back("foo");
73 names.emplace_back("bar");
74 names.emplace_back("baz");
75 names.emplace_back("qux");
80 schem.schemdata = new MapNode[volume];
81 schem.slice_probs = new u8[size.Y];
82 for (size_t i = 0; i != volume; i++)
83 schem.schemdata[i] = MapNode(test_schem1_data[i], MTSCHEM_PROB_ALWAYS, 0);
84 for (s16 y = 0; y != size.Y; y++)
85 schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS;
87 UASSERT(schem.serializeToMts(&ss));
92 UASSERT(schem2.deserializeFromMts(&ss));
95 std::vector<std::string> &names = schem2.m_nodenames;
96 UASSERTEQ(size_t, names.size(), 4);
97 UASSERTEQ(std::string, names[0], "foo");
98 UASSERTEQ(std::string, names[1], "bar");
99 UASSERTEQ(std::string, names[2], "baz");
100 UASSERTEQ(std::string, names[3], "qux");
103 UASSERT(schem2.size == size);
104 for (size_t i = 0; i != volume; i++)
105 UASSERT(schem2.schemdata[i] == schem.schemdata[i]);
106 for (s16 y = 0; y != size.Y; y++)
107 UASSERTEQ(u8, schem2.slice_probs[y], schem.slice_probs[y]);
111 void TestSchematic::testLuaTableSerialize(const NodeDefManager *ndef)
113 static const v3s16 size(3, 3, 3);
114 static const u32 volume = size.X * size.Y * size.Z;
120 schem.schemdata = new MapNode[volume];
121 schem.slice_probs = new u8[size.Y];
122 for (size_t i = 0; i != volume; i++)
123 schem.schemdata[i] = MapNode(test_schem2_data[i], test_schem2_prob[i], 0);
124 for (s16 y = 0; y != size.Y; y++)
125 schem.slice_probs[y] = MTSCHEM_PROB_ALWAYS;
127 std::vector<std::string> &names = schem.m_nodenames;
128 names.emplace_back("air");
129 names.emplace_back("default:lava_source");
130 names.emplace_back("default:glass");
132 std::ostringstream ss(std::ios_base::binary);
134 UASSERT(schem.serializeToLua(&ss, false, 0));
135 UASSERTEQ(std::string, ss.str(), expected_lua_output);
139 void TestSchematic::testFileSerializeDeserialize(const NodeDefManager *ndef)
141 static const v3s16 size(3, 3, 3);
142 static const u32 volume = size.X * size.Y * size.Z;
143 static const content_t content_map[] = {
148 static const content_t content_map2[] = {
153 StringMap replace_names;
154 replace_names["default:lava"] = "default:water";
156 Schematic schem1, schem2;
158 //// Construct the schematic to save
161 schem1.schemdata = new MapNode[volume];
162 schem1.slice_probs = new u8[size.Y];
163 schem1.slice_probs[0] = 80;
164 schem1.slice_probs[1] = 160;
165 schem1.slice_probs[2] = 240;
166 // Node resolving happened manually.
167 schem1.m_resolve_done = true;
169 for (size_t i = 0; i != volume; i++) {
170 content_t c = content_map[test_schem2_data[i]];
171 schem1.schemdata[i] = MapNode(c, test_schem2_prob[i], 0);
174 std::string temp_file = getTestTempFile();
175 UASSERT(schem1.saveSchematicToFile(temp_file, ndef));
176 UASSERT(schem2.loadSchematicFromFile(temp_file, ndef, &replace_names));
178 UASSERT(schem2.size == size);
179 UASSERT(schem2.slice_probs[0] == 80);
180 UASSERT(schem2.slice_probs[1] == 160);
181 UASSERT(schem2.slice_probs[2] == 240);
183 for (size_t i = 0; i != volume; i++) {
184 content_t c = content_map2[test_schem2_data[i]];
185 UASSERT(schem2.schemdata[i] == MapNode(c, test_schem2_prob[i], 0));
190 // Should form a cross-shaped-thing...?
191 const content_t TestSchematic::test_schem1_data[7 * 6 * 4] = {
192 3, 3, 1, 1, 1, 3, 3, // Y=0, Z=0
193 3, 0, 1, 2, 1, 0, 3, // Y=1, Z=0
194 3, 0, 1, 2, 1, 0, 3, // Y=2, Z=0
195 3, 1, 1, 2, 1, 1, 3, // Y=3, Z=0
196 3, 2, 2, 2, 2, 2, 3, // Y=4, Z=0
197 3, 1, 1, 2, 1, 1, 3, // Y=5, Z=0
199 0, 0, 1, 1, 1, 0, 0, // Y=0, Z=1
200 0, 0, 1, 2, 1, 0, 0, // Y=1, Z=1
201 0, 0, 1, 2, 1, 0, 0, // Y=2, Z=1
202 1, 1, 1, 2, 1, 1, 1, // Y=3, Z=1
203 1, 2, 2, 2, 2, 2, 1, // Y=4, Z=1
204 1, 1, 1, 2, 1, 1, 1, // Y=5, Z=1
206 0, 0, 1, 1, 1, 0, 0, // Y=0, Z=2
207 0, 0, 1, 2, 1, 0, 0, // Y=1, Z=2
208 0, 0, 1, 2, 1, 0, 0, // Y=2, Z=2
209 1, 1, 1, 2, 1, 1, 1, // Y=3, Z=2
210 1, 2, 2, 2, 2, 2, 1, // Y=4, Z=2
211 1, 1, 1, 2, 1, 1, 1, // Y=5, Z=2
213 3, 3, 1, 1, 1, 3, 3, // Y=0, Z=3
214 3, 0, 1, 2, 1, 0, 3, // Y=1, Z=3
215 3, 0, 1, 2, 1, 0, 3, // Y=2, Z=3
216 3, 1, 1, 2, 1, 1, 3, // Y=3, Z=3
217 3, 2, 2, 2, 2, 2, 3, // Y=4, Z=3
218 3, 1, 1, 2, 1, 1, 3, // Y=5, Z=3
221 const content_t TestSchematic::test_schem2_data[3 * 3 * 3] = {
235 const u8 TestSchematic::test_schem2_prob[3 * 3 * 3] = {
249 const char *TestSchematic::expected_lua_output =
251 "\tsize = {x=3, y=3, z=3},\n"
252 "\tyslice_prob = {\n"
253 "\t\t{ypos=0, prob=254},\n"
254 "\t\t{ypos=1, prob=254},\n"
255 "\t\t{ypos=2, prob=254},\n"
258 "\t\t{name=\"air\", prob=0, param2=0},\n"
259 "\t\t{name=\"air\", prob=0, param2=0},\n"
260 "\t\t{name=\"air\", prob=0, param2=0},\n"
261 "\t\t{name=\"air\", prob=0, param2=0},\n"
262 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
263 "\t\t{name=\"air\", prob=0, param2=0},\n"
264 "\t\t{name=\"air\", prob=0, param2=0},\n"
265 "\t\t{name=\"air\", prob=0, param2=0},\n"
266 "\t\t{name=\"air\", prob=0, param2=0},\n"
267 "\t\t{name=\"air\", prob=0, param2=0},\n"
268 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
269 "\t\t{name=\"air\", prob=0, param2=0},\n"
270 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
271 "\t\t{name=\"default:lava_source\", prob=254, param2=0, force_place=true},\n"
272 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
273 "\t\t{name=\"air\", prob=0, param2=0},\n"
274 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
275 "\t\t{name=\"air\", prob=0, param2=0},\n"
276 "\t\t{name=\"air\", prob=0, param2=0},\n"
277 "\t\t{name=\"air\", prob=0, param2=0},\n"
278 "\t\t{name=\"air\", prob=0, param2=0},\n"
279 "\t\t{name=\"air\", prob=0, param2=0},\n"
280 "\t\t{name=\"default:glass\", prob=254, param2=0, force_place=true},\n"
281 "\t\t{name=\"air\", prob=0, param2=0},\n"
282 "\t\t{name=\"air\", prob=0, param2=0},\n"
283 "\t\t{name=\"air\", prob=0, param2=0},\n"
284 "\t\t{name=\"air\", prob=0, param2=0},\n"