]> git.localhorst.tv Git - blank.git/blob - tst/world/ChunkTest.cpp
more unit tests for Packet
[blank.git] / tst / world / ChunkTest.cpp
1 #include "ChunkTest.hpp"
2
3 #include "world/BlockType.hpp"
4 #include "world/Chunk.hpp"
5
6 #include <memory>
7
8 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::ChunkTest);
9
10 using std::unique_ptr;
11
12
13 namespace blank {
14 namespace test {
15
16 void ChunkTest::setUp() {
17         types = BlockTypeRegistry();
18
19         BlockType obstacle;
20         obstacle.visible = true;
21         obstacle.block_light = true;
22         types.Add(obstacle);
23
24         BlockType source;
25         source.visible = true;
26         source.luminosity = 5;
27         source.block_light = true;
28         types.Add(source);
29 }
30
31 void ChunkTest::tearDown() {
32 }
33
34
35 void ChunkTest::testBounds() {
36         CPPUNIT_ASSERT_MESSAGE(
37                 "valid position out of bounds",
38                 Chunk::InBounds(Chunk::Pos(0, 0, 0))
39         );
40         CPPUNIT_ASSERT_MESSAGE(
41                 "valid position out of bounds",
42                 Chunk::InBounds(Chunk::Pos(15, 0, 0))
43         );
44         CPPUNIT_ASSERT_MESSAGE(
45                 "valid position out of bounds",
46                 Chunk::InBounds(Chunk::Pos(0, 15, 0))
47         );
48         CPPUNIT_ASSERT_MESSAGE(
49                 "valid position out of bounds",
50                 Chunk::InBounds(Chunk::Pos(0, 0, 15))
51         );
52         CPPUNIT_ASSERT_MESSAGE(
53                 "valid position out of bounds",
54                 Chunk::InBounds(Chunk::Pos(15, 15, 15))
55         );
56         CPPUNIT_ASSERT_MESSAGE(
57                 "invalid position in bounds",
58                 !Chunk::InBounds(Chunk::Pos(-1, -1, -1))
59         );
60         CPPUNIT_ASSERT_MESSAGE(
61                 "invalid position in bounds",
62                 !Chunk::InBounds(Chunk::Pos(-1, 1, 0))
63         );
64         CPPUNIT_ASSERT_MESSAGE(
65                 "invalid position in bounds",
66                 !Chunk::InBounds(Chunk::Pos(16, -16, 0))
67         );
68         CPPUNIT_ASSERT_MESSAGE(
69                 "invalid position in bounds",
70                 !Chunk::InBounds(Chunk::Pos(16, 16, 16))
71         );
72 }
73
74 void ChunkTest::testBorder() {
75         CPPUNIT_ASSERT_MESSAGE(
76                 "position not border",
77                 Chunk::IsBorder(Chunk::Pos(0, 0, 0))
78         );
79         CPPUNIT_ASSERT_MESSAGE(
80                 "position not border",
81                 Chunk::IsBorder(Chunk::Pos(0, 0, 8))
82         );
83         CPPUNIT_ASSERT_MESSAGE(
84                 "position not border",
85                 Chunk::IsBorder(Chunk::Pos(0, 0, 15))
86         );
87         CPPUNIT_ASSERT_MESSAGE(
88                 "position not border",
89                 Chunk::IsBorder(Chunk::Pos(0, 8, 0))
90         );
91         CPPUNIT_ASSERT_MESSAGE(
92                 "position not border",
93                 Chunk::IsBorder(Chunk::Pos(0, 8, 8))
94         );
95         CPPUNIT_ASSERT_MESSAGE(
96                 "position not border",
97                 Chunk::IsBorder(Chunk::Pos(0, 8, 15))
98         );
99         CPPUNIT_ASSERT_MESSAGE(
100                 "position not border",
101                 Chunk::IsBorder(Chunk::Pos(0, 15, 0))
102         );
103         CPPUNIT_ASSERT_MESSAGE(
104                 "position not border",
105                 Chunk::IsBorder(Chunk::Pos(0, 15, 8))
106         );
107         CPPUNIT_ASSERT_MESSAGE(
108                 "position not border",
109                 Chunk::IsBorder(Chunk::Pos(0, 15, 15))
110         );
111         CPPUNIT_ASSERT_MESSAGE(
112                 "position not border",
113                 Chunk::IsBorder(Chunk::Pos(8, 0, 0))
114         );
115         CPPUNIT_ASSERT_MESSAGE(
116                 "position not border",
117                 Chunk::IsBorder(Chunk::Pos(8, 0, 8))
118         );
119         CPPUNIT_ASSERT_MESSAGE(
120                 "position not border",
121                 Chunk::IsBorder(Chunk::Pos(8, 0, 15))
122         );
123         CPPUNIT_ASSERT_MESSAGE(
124                 "position not border",
125                 Chunk::IsBorder(Chunk::Pos(8, 8, 0))
126         );
127         CPPUNIT_ASSERT_MESSAGE(
128                 "position is border",
129                 !Chunk::IsBorder(Chunk::Pos(8, 8, 8))
130         );
131         CPPUNIT_ASSERT_MESSAGE(
132                 "position not border",
133                 Chunk::IsBorder(Chunk::Pos(8, 8, 15))
134         );
135         CPPUNIT_ASSERT_MESSAGE(
136                 "position not border",
137                 Chunk::IsBorder(Chunk::Pos(8, 15, 0))
138         );
139         CPPUNIT_ASSERT_MESSAGE(
140                 "position not border",
141                 Chunk::IsBorder(Chunk::Pos(8, 15, 8))
142         );
143         CPPUNIT_ASSERT_MESSAGE(
144                 "position not border",
145                 Chunk::IsBorder(Chunk::Pos(8, 15, 15))
146         );
147         CPPUNIT_ASSERT_MESSAGE(
148                 "position not border",
149                 Chunk::IsBorder(Chunk::Pos(15, 0, 0))
150         );
151         CPPUNIT_ASSERT_MESSAGE(
152                 "position not border",
153                 Chunk::IsBorder(Chunk::Pos(15, 0, 8))
154         );
155         CPPUNIT_ASSERT_MESSAGE(
156                 "position not border",
157                 Chunk::IsBorder(Chunk::Pos(15, 0, 15))
158         );
159         CPPUNIT_ASSERT_MESSAGE(
160                 "position not border",
161                 Chunk::IsBorder(Chunk::Pos(15, 8, 0))
162         );
163         CPPUNIT_ASSERT_MESSAGE(
164                 "position not border",
165                 Chunk::IsBorder(Chunk::Pos(15, 8, 8))
166         );
167         CPPUNIT_ASSERT_MESSAGE(
168                 "position not border",
169                 Chunk::IsBorder(Chunk::Pos(15, 8, 15))
170         );
171         CPPUNIT_ASSERT_MESSAGE(
172                 "position not border",
173                 Chunk::IsBorder(Chunk::Pos(15, 15, 0))
174         );
175         CPPUNIT_ASSERT_MESSAGE(
176                 "position not border",
177                 Chunk::IsBorder(Chunk::Pos(15, 15, 8))
178         );
179         CPPUNIT_ASSERT_MESSAGE(
180                 "position not border",
181                 Chunk::IsBorder(Chunk::Pos(15, 15, 15))
182         );
183
184         CPPUNIT_ASSERT_MESSAGE(
185                 "position not border",
186                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 0)))
187         );
188         CPPUNIT_ASSERT_MESSAGE(
189                 "position not border",
190                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 8)))
191         );
192         CPPUNIT_ASSERT_MESSAGE(
193                 "position not border",
194                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 0, 15)))
195         );
196         CPPUNIT_ASSERT_MESSAGE(
197                 "position not border",
198                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 0)))
199         );
200         CPPUNIT_ASSERT_MESSAGE(
201                 "position not border",
202                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 8)))
203         );
204         CPPUNIT_ASSERT_MESSAGE(
205                 "position not border",
206                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 8, 15)))
207         );
208         CPPUNIT_ASSERT_MESSAGE(
209                 "position not border",
210                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 0)))
211         );
212         CPPUNIT_ASSERT_MESSAGE(
213                 "position not border",
214                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 8)))
215         );
216         CPPUNIT_ASSERT_MESSAGE(
217                 "position not border",
218                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(0, 15, 15)))
219         );
220         CPPUNIT_ASSERT_MESSAGE(
221                 "position not border",
222                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 0)))
223         );
224         CPPUNIT_ASSERT_MESSAGE(
225                 "position not border",
226                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 8)))
227         );
228         CPPUNIT_ASSERT_MESSAGE(
229                 "position not border",
230                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 0, 15)))
231         );
232         CPPUNIT_ASSERT_MESSAGE(
233                 "position not border",
234                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 0)))
235         );
236         CPPUNIT_ASSERT_MESSAGE(
237                 "position is border",
238                 !Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 8)))
239         );
240         CPPUNIT_ASSERT_MESSAGE(
241                 "position not border",
242                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 8, 15)))
243         );
244         CPPUNIT_ASSERT_MESSAGE(
245                 "position not border",
246                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 0)))
247         );
248         CPPUNIT_ASSERT_MESSAGE(
249                 "position not border",
250                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 8)))
251         );
252         CPPUNIT_ASSERT_MESSAGE(
253                 "position not border",
254                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(8, 15, 15)))
255         );
256         CPPUNIT_ASSERT_MESSAGE(
257                 "position not border",
258                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 0)))
259         );
260         CPPUNIT_ASSERT_MESSAGE(
261                 "position not border",
262                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 8)))
263         );
264         CPPUNIT_ASSERT_MESSAGE(
265                 "position not border",
266                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 0, 15)))
267         );
268         CPPUNIT_ASSERT_MESSAGE(
269                 "position not border",
270                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 0)))
271         );
272         CPPUNIT_ASSERT_MESSAGE(
273                 "position not border",
274                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 8)))
275         );
276         CPPUNIT_ASSERT_MESSAGE(
277                 "position not border",
278                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 8, 15)))
279         );
280         CPPUNIT_ASSERT_MESSAGE(
281                 "position not border",
282                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 0)))
283         );
284         CPPUNIT_ASSERT_MESSAGE(
285                 "position not border",
286                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 8)))
287         );
288         CPPUNIT_ASSERT_MESSAGE(
289                 "position not border",
290                 Chunk::IsBorder(Chunk::ToIndex(Chunk::Pos(15, 15, 15)))
291         );
292 }
293
294 void ChunkTest::testNeighbor() {
295         unique_ptr<Chunk> chunk(new Chunk(types));
296         chunk->Position({0, 0, 0});
297         for (int i = 0; i < Block::FACE_COUNT; ++i) {
298                 CPPUNIT_ASSERT_MESSAGE(
299                         "sole chunk has neighbor",
300                         !chunk->HasNeighbor(Block::Face(i))
301                 );
302         }
303
304         unique_ptr<Chunk> neighbor(new Chunk(types));
305         for (int i = 0; i < Block::FACE_COUNT; ++i) {
306                 Block::Face face = Block::Face(i);
307                 neighbor->Position(Block::FaceNormal(face));
308                 chunk->SetNeighbor(face, *neighbor);
309                 CPPUNIT_ASSERT_MESSAGE(
310                         "chunk did not link right neighbor",
311                         chunk->HasNeighbor(face)
312                 );
313                 CPPUNIT_ASSERT_MESSAGE(
314                         "chunk did not link right neighbor",
315                         neighbor->HasNeighbor(Block::Opposite(face))
316                 );
317                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
318                         "chunk did not link correct neighbor",
319                         &*neighbor, &chunk->GetNeighbor(face)
320                 );
321                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
322                         "chunk did not link correct neighbor",
323                         &*chunk, &neighbor->GetNeighbor(Block::Opposite(face))
324                 );
325                 chunk->Unlink();
326         }
327 }
328
329
330 void ChunkTest::testBlock() {
331         unique_ptr<Chunk> chunk(new Chunk(types));
332
333         for (int index = 0; index < Chunk::size; ++index) {
334                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
335                         "default chunk has non-default block",
336                         Block(), chunk->BlockAt(index)
337                 );
338         }
339
340         Block block(1, Block::FACE_LEFT, Block::TURN_RIGHT);
341         chunk->SetBlock(0, block);
342         CPPUNIT_ASSERT_EQUAL_MESSAGE(
343                 "wrong type on set block",
344                 block.type, chunk->BlockAt(0).type
345         );
346         CPPUNIT_ASSERT_EQUAL_MESSAGE(
347                 "wrong orientation on set block",
348                 block.orient, chunk->BlockAt(0).orient
349         );
350         for (int index = 1; index < Chunk::size; ++index) {
351                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
352                         "changing block at index 0 affected some other block",
353                         Block(), chunk->BlockAt(index)
354                 );
355         }
356 }
357
358 void ChunkTest::testLight() {
359         unique_ptr<Chunk> chunk(new Chunk(types));
360
361         for (int index = 0; index < Chunk::size; ++index) {
362                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
363                         "default chunk has non-zero light level",
364                         0, chunk->GetLight(index)
365                 );
366         }
367
368         chunk->SetLight(0, 15);
369         CPPUNIT_ASSERT_EQUAL_MESSAGE(
370                 "wrong light level on set index",
371                 15, chunk->GetLight(0)
372         );
373         for (int index = 1; index < Chunk::size; ++index) {
374                 CPPUNIT_ASSERT_EQUAL_MESSAGE(
375                         "changing light at index 0 affected some other index",
376                         0, chunk->GetLight(index)
377                 );
378         }
379 }
380
381 void ChunkTest::testLightPropagation() {
382         unique_ptr<Chunk> chunk(new Chunk(types));
383
384         // 0 air, 1 solid, 2 solid and emits light level of 5
385         chunk->SetBlock(Chunk::Pos(7, 7, 7), Block(2));
386         CPPUNIT_ASSERT_EQUAL_MESSAGE(
387                 "adding luminant block did not set correct light level",
388                 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
389         );
390
391         CPPUNIT_ASSERT_EQUAL_MESSAGE(
392                 "light did not propagate correctly in +X",
393                 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
394         );
395         CPPUNIT_ASSERT_EQUAL_MESSAGE(
396                 "light did not propagate correctly in -X",
397                 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
398         );
399         CPPUNIT_ASSERT_EQUAL_MESSAGE(
400                 "light did not propagate correctly in +Y",
401                 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
402         );
403         CPPUNIT_ASSERT_EQUAL_MESSAGE(
404                 "light did not propagate correctly in -Y",
405                 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
406         );
407         CPPUNIT_ASSERT_EQUAL_MESSAGE(
408                 "light did not propagate correctly in +Z",
409                 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
410         );
411         CPPUNIT_ASSERT_EQUAL_MESSAGE(
412                 "light did not propagate correctly in -Z",
413                 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
414         );
415
416         CPPUNIT_ASSERT_EQUAL_MESSAGE(
417                 "light did not propagate correctly in 2D diagonal",
418                 3, chunk->GetLight(Chunk::Pos(8, 8, 7))
419         );
420         CPPUNIT_ASSERT_EQUAL_MESSAGE(
421                 "light did not propagate correctly in 2D diagonal",
422                 3, chunk->GetLight(Chunk::Pos(7, 6, 8))
423         );
424         CPPUNIT_ASSERT_EQUAL_MESSAGE(
425                 "light did not propagate correctly in 2D diagonal",
426                 3, chunk->GetLight(Chunk::Pos(6, 7, 8))
427         );
428
429         CPPUNIT_ASSERT_EQUAL_MESSAGE(
430                 "light did not propagate correctly in 3D diagonal",
431                 2, chunk->GetLight(Chunk::Pos(8, 6, 6))
432         );
433         CPPUNIT_ASSERT_EQUAL_MESSAGE(
434                 "light did not propagate correctly in 3D diagonal",
435                 2, chunk->GetLight(Chunk::Pos(6, 6, 8))
436         );
437         CPPUNIT_ASSERT_EQUAL_MESSAGE(
438                 "light did not propagate correctly in 3D diagonal",
439                 2, chunk->GetLight(Chunk::Pos(6, 8, 8))
440         );
441
442         // now block the light to the left
443         chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(1));
444         CPPUNIT_ASSERT_EQUAL_MESSAGE(
445                 "adding obstacle affected unrelated index",
446                 5, chunk->GetLight(Chunk::Pos(7, 7, 7))
447         );
448         CPPUNIT_ASSERT_EQUAL_MESSAGE(
449                 "adding obstacle affected unrelated index",
450                 4, chunk->GetLight(Chunk::Pos(8, 7, 7))
451         );
452         CPPUNIT_ASSERT_EQUAL_MESSAGE(
453                 "adding obstacle affected unrelated index",
454                 4, chunk->GetLight(Chunk::Pos(7, 8, 7))
455         );
456         CPPUNIT_ASSERT_EQUAL_MESSAGE(
457                 "adding obstacle affected unrelated index",
458                 4, chunk->GetLight(Chunk::Pos(7, 6, 7))
459         );
460         CPPUNIT_ASSERT_EQUAL_MESSAGE(
461                 "adding obstacle affected unrelated index",
462                 4, chunk->GetLight(Chunk::Pos(7, 7, 8))
463         );
464         CPPUNIT_ASSERT_EQUAL_MESSAGE(
465                 "adding obstacle affected unrelated index",
466                 4, chunk->GetLight(Chunk::Pos(7, 7, 6))
467         );
468         CPPUNIT_ASSERT_EQUAL_MESSAGE(
469                 "adding obstacle affected unrelated index",
470                 3, chunk->GetLight(Chunk::Pos(6, 6, 7))
471         );
472         CPPUNIT_ASSERT_EQUAL_MESSAGE(
473                 "adding obstacle affected unrelated index",
474                 3, chunk->GetLight(Chunk::Pos(6, 8, 7))
475         );
476         CPPUNIT_ASSERT_EQUAL_MESSAGE(
477                 "adding obstacle affected unrelated index",
478                 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
479         );
480         CPPUNIT_ASSERT_EQUAL_MESSAGE(
481                 "adding obstacle affected unrelated index",
482                 3, chunk->GetLight(Chunk::Pos(6, 7, 6))
483         );
484         CPPUNIT_ASSERT_EQUAL_MESSAGE(
485                 "adding obstacle affected unrelated index",
486                 2, chunk->GetLight(Chunk::Pos(5, 6, 7))
487         );
488         CPPUNIT_ASSERT_EQUAL_MESSAGE(
489                 "adding obstacle affected unrelated index",
490                 2, chunk->GetLight(Chunk::Pos(5, 8, 7))
491         );
492         CPPUNIT_ASSERT_EQUAL_MESSAGE(
493                 "adding obstacle affected unrelated index",
494                 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
495         );
496         CPPUNIT_ASSERT_EQUAL_MESSAGE(
497                 "adding obstacle affected unrelated index",
498                 2, chunk->GetLight(Chunk::Pos(5, 7, 6))
499         );
500         CPPUNIT_ASSERT_EQUAL_MESSAGE(
501                 "adding obstacle resulted in unexpected light level behind it",
502                 1, chunk->GetLight(Chunk::Pos(5, 7, 7))
503         );
504
505         // and remove it again
506         chunk->SetBlock(Chunk::Pos(6, 7, 7), Block(0));
507         CPPUNIT_ASSERT_EQUAL_MESSAGE(
508                 "removing obstacle did not refill light correctly",
509                 4, chunk->GetLight(Chunk::Pos(6, 7, 7))
510         );
511         CPPUNIT_ASSERT_EQUAL_MESSAGE(
512                 "removing obstacle did not refill light correctly",
513                 3, chunk->GetLight(Chunk::Pos(5, 7, 7))
514         );
515         CPPUNIT_ASSERT_EQUAL_MESSAGE(
516                 "removing obstacle did not refill light correctly",
517                 2, chunk->GetLight(Chunk::Pos(4, 7, 7))
518         );
519 }
520
521 }
522 }