]> git.lizzy.rs Git - dragonfireclient.git/blob - src/unittest/test_schematic.cpp
Require 'basic_debug' priv to view gameplay-relevant debug info, require 'debug'...
[dragonfireclient.git] / src / unittest / test_schematic.cpp
1  /*
2 Minetest
3 Copyright (C) 2010-2014 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
4
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.
9
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.
14
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.
18 */
19
20 #include "test.h"
21
22 #include "mapgen/mg_schematic.h"
23 #include "gamedef.h"
24 #include "nodedef.h"
25
26 class TestSchematic : public TestBase {
27 public:
28         TestSchematic() { TestManager::registerTestModule(this); }
29         const char *getName() { return "TestSchematic"; }
30
31         void runTests(IGameDef *gamedef);
32
33         void testMtsSerializeDeserialize(const NodeDefManager *ndef);
34         void testLuaTableSerialize(const NodeDefManager *ndef);
35         void testFileSerializeDeserialize(const NodeDefManager *ndef);
36
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;
41 };
42
43 static TestSchematic g_test_instance;
44
45 void TestSchematic::runTests(IGameDef *gamedef)
46 {
47         NodeDefManager *ndef =
48                 (NodeDefManager *)gamedef->getNodeDefManager();
49
50         ndef->setNodeRegistrationStatus(true);
51
52         TEST(testMtsSerializeDeserialize, ndef);
53         TEST(testLuaTableSerialize, ndef);
54         TEST(testFileSerializeDeserialize, ndef);
55
56         ndef->resetNodeResolveState();
57 }
58
59 ////////////////////////////////////////////////////////////////////////////////
60
61 void TestSchematic::testMtsSerializeDeserialize(const NodeDefManager *ndef)
62 {
63         static const v3s16 size(7, 6, 4);
64         static const u32 volume = size.X * size.Y * size.Z;
65
66         std::stringstream ss(std::ios_base::binary |
67                 std::ios_base::in | std::ios_base::out);
68
69         Schematic schem;
70         {
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");
76         }
77
78         schem.flags       = 0;
79         schem.size        = size;
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;
86
87         UASSERT(schem.serializeToMts(&ss));
88
89         ss.seekg(0);
90
91         Schematic schem2;
92         UASSERT(schem2.deserializeFromMts(&ss));
93
94         {
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");
101         }
102
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]);
108 }
109
110
111 void TestSchematic::testLuaTableSerialize(const NodeDefManager *ndef)
112 {
113         static const v3s16 size(3, 3, 3);
114         static const u32 volume = size.X * size.Y * size.Z;
115
116         Schematic schem;
117
118         schem.flags       = 0;
119         schem.size        = size;
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;
126
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");
131
132         std::ostringstream ss(std::ios_base::binary);
133
134         UASSERT(schem.serializeToLua(&ss, false, 0));
135         UASSERTEQ(std::string, ss.str(), expected_lua_output);
136 }
137
138
139 void TestSchematic::testFileSerializeDeserialize(const NodeDefManager *ndef)
140 {
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[] = {
144                 CONTENT_AIR,
145                 t_CONTENT_STONE,
146                 t_CONTENT_LAVA,
147         };
148         static const content_t content_map2[] = {
149                 CONTENT_AIR,
150                 t_CONTENT_STONE,
151                 t_CONTENT_WATER,
152         };
153         StringMap replace_names;
154         replace_names["default:lava"] = "default:water";
155
156         Schematic schem1, schem2;
157
158         //// Construct the schematic to save
159         schem1.flags          = 0;
160         schem1.size           = size;
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;
168
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);
172         }
173
174         std::string temp_file = getTestTempFile();
175         UASSERT(schem1.saveSchematicToFile(temp_file, ndef));
176         UASSERT(schem2.loadSchematicFromFile(temp_file, ndef, &replace_names));
177
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);
182
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));
186         }
187 }
188
189
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
198
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
205
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
212
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
219 };
220
221 const content_t TestSchematic::test_schem2_data[3 * 3 * 3] = {
222         0, 0, 0,
223         0, 2, 0,
224         0, 0, 0,
225
226         0, 2, 0,
227         2, 1, 2,
228         0, 2, 0,
229
230         0, 0, 0,
231         0, 2, 0,
232         0, 0, 0,
233 };
234
235 const u8 TestSchematic::test_schem2_prob[3 * 3 * 3] = {
236         0x00, 0x00, 0x00,
237         0x00, 0xFF, 0x00,
238         0x00, 0x00, 0x00,
239
240         0x00, 0xFF, 0x00,
241         0xFF, 0xFF, 0xFF,
242         0x00, 0xFF, 0x00,
243
244         0x00, 0x00, 0x00,
245         0x00, 0xFF, 0x00,
246         0x00, 0x00, 0x00,
247 };
248
249 const char *TestSchematic::expected_lua_output =
250         "schematic = {\n"
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"
256         "\t},\n"
257         "\tdata = {\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"
285         "\t},\n"
286         "}\n";