The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
test_image_modifications.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2011 - 2025
3 by Karol Kozub <karol.alt@gmail.com>
4 Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
12
13 See the COPYING file for more details.
14*/
15
16#define GETTEXT_DOMAIN "wesnoth-test"
17
18#include <boost/test/unit_test.hpp>
19#include <sstream>
20
21#include "game_config.hpp"
22#include "game_config_view.hpp"
23#include "config_cache.hpp"
24#include "config.hpp"
25#include "color_range.hpp"
26#include "picture.hpp"
28#include "log.hpp"
29#include "filesystem.hpp"
30
31using namespace image;
32
33namespace {
34/** Sets up the environment for every test */
35class environment_setup
36{
37public:
38 environment_setup()
39 // redirects the output to an ignored stream
40 : ignored_stream_()
41 , output_redirect_(ignored_stream_)
42 , paths_manager_()
43 {
44 set_up_color_info();
45 set_up_image_paths();
46 }
47
48private:
49 /** Sets up color_info configuration
50 *
51 * This is required by the RC modifications
52 */
53 void set_up_color_info()
54 {
55 const auto cfg = config{
56 "color_range", config{
57 "id", "red",
58 "name", "Red",
59 "rgb", "FF0000,FFFFFF,000000,FF0000"
60 },
61 "color_range", config{
62 "id", "blue",
63 "name", "Blue",
64 "rgb", "2E419B,FFFFFF,0F0F0F,0000FF"
65 }
66 };
67
69 }
70
71 /** Sets up the paths later used to load images
72 *
73 * This is required by all the modifications that use image::get_surface
74 * to load images from disk
75 */
76 void set_up_image_paths()
77 {
78 const auto cfg = config{"binary_path", config{"path", "data/core"}};
79 paths_manager_.set_paths(game_config_view::wrap(cfg));
80 }
81
82 std::stringstream ignored_stream_;
83 lg::redirect_output_setter output_redirect_;
85};
86} // anonymous namespace
87
88BOOST_AUTO_TEST_SUITE(image_modification_parsing)
89
90/** Tests if modifications with a higher priority are placed before the others
91 *
92 * The RC modification has a higher priority than other modifications and has
93 * to be applied before all the others. This test checks if that order is taken
94 * care of by the queue.
95 */
96BOOST_AUTO_TEST_CASE(test_modificaiton_queue_order)
97{
98 environment_setup env_setup;
99
100 modification_queue queue;
101
102 auto low_priority_mod = std::make_unique<fl_modification>();
103 auto high_priority_mod = std::make_unique<rc_modification>();
104
105 modification* lptr = low_priority_mod.get();
106 modification* hptr = high_priority_mod.get();
107
108 queue.push(std::move(low_priority_mod));
109 queue.push(std::move(high_priority_mod));
110
111 BOOST_REQUIRE_EQUAL(queue.size(), 2);
112
113 BOOST_CHECK_EQUAL(&queue.top(), hptr);
114 queue.pop();
115 BOOST_CHECK_EQUAL(&queue.top(), lptr);
116 queue.pop();
117
118 low_priority_mod = std::make_unique<fl_modification>();
119 high_priority_mod = std::make_unique<rc_modification>();
120
121 lptr = low_priority_mod.get();
122 hptr = high_priority_mod.get();
123
124 // reverse insertion order now
125 queue.push(std::move(high_priority_mod));
126 queue.push(std::move(low_priority_mod));
127
128 BOOST_REQUIRE_EQUAL(queue.size(), 2);
129
130 BOOST_CHECK_EQUAL(&queue.top(), hptr);
131 queue.pop();
132 BOOST_CHECK_EQUAL(&queue.top(), lptr);
133 queue.pop();
134}
135
136/** Tests if the TC modification is correctly decoded */
137BOOST_AUTO_TEST_CASE(test_tc_modification_decoding)
138{
139 environment_setup env_setup;
140
141 modification_queue queue = modification::decode("~TC(1,blue)");
142
143 BOOST_REQUIRE_EQUAL(queue.size(), 1);
144
145 auto mod = dynamic_cast<const rc_modification*>(&queue.top());
146
147 // The dynamic_cast returns nullptr if the argument doesn't match the type
148 BOOST_REQUIRE(mod != nullptr);
149
150 const std::vector<color_t>& old_color = game_config::tc_info("blue");
151 // The first team color is red
152 const color_range& new_color = game_config::color_info("red");
153 color_mapping expected = generate_color_mapping(new_color, old_color);
154
155 BOOST_CHECK(expected == mod->map());
156}
157
158/** Tests if the TC modification with invalid arguments is ignored */
159BOOST_AUTO_TEST_CASE(test_tc_modification_decoding_invalid_args)
160{
161 environment_setup env_setup;
162
163 modification_queue queue = modification::decode("~TC()~TC(1)~TC(0,blue)");
164
165 BOOST_REQUIRE_EQUAL(queue.size(), 0);
166}
167
168/** Tests if the RC modification is correctly decoded */
169BOOST_AUTO_TEST_CASE(test_rc_modification_decoding)
170{
171 environment_setup env_setup;
172
173 modification_queue queue = modification::decode("~RC(red>blue)");
174
175 BOOST_REQUIRE_EQUAL(queue.size(), 1);
176
177 auto mod = dynamic_cast<const rc_modification*>(&queue.top());
178
179 // The dynamic_cast returns nullptr if the argument doesn't match the type
180 BOOST_REQUIRE(mod != nullptr);
181
182 const std::vector<color_t>& old_color = game_config::tc_info("red");
183 const color_range& new_color = game_config::color_info("blue");
184 color_mapping expected = generate_color_mapping(new_color, old_color);
185
186 BOOST_CHECK(expected == mod->map());
187}
188
189/** Tests if the RC modification with invalid arguments is ignored */
190BOOST_AUTO_TEST_CASE(test_rc_modification_decoding_invalid_args)
191{
192 environment_setup env_setup;
193
194 modification_queue queue = modification::decode("~RC()~RC(blue)~RC(>)");
195
196 BOOST_REQUIRE_EQUAL(queue.size(), 0);
197}
198
199/** Tests if the PAL modification is correctly decoded */
200BOOST_AUTO_TEST_CASE(test_pal_modification_decoding)
201{
202 environment_setup env_setup;
203
204 modification_queue queue =
205 modification::decode("~PAL(000000,005000 > FFFFFF,FF00FF)");
206
207 BOOST_REQUIRE_EQUAL(queue.size(), 1);
208
209 auto mod = dynamic_cast<const rc_modification*>(&queue.top());
210
211 // The dynamic_cast returns nullptr if the argument doesn't match the type
212 BOOST_REQUIRE(mod != nullptr);
213
214 const std::vector<color_t>& old_palette = game_config::tc_info("000000,005000");
215 const std::vector<color_t>& new_palette = game_config::tc_info("FFFFFF,FF00FF");
216 color_mapping expected;
217
218 for(std::size_t i = 0; i < old_palette.size() && i < new_palette.size(); ++i) {
219 environment_setup env_setup;
220
221 expected[old_palette[i]] = new_palette[i];
222 }
223
224 BOOST_CHECK(expected == mod->map());
225}
226
227/** Tests if the PAL modification with invalid arguments is ignored */
228BOOST_AUTO_TEST_CASE(test_pal_modification_decoding_invalid_args)
229{
230 environment_setup env_setup;
231
232 modification_queue queue =
233 modification::decode("~PAL()~PAL(>)");
234
235 BOOST_REQUIRE_EQUAL(queue.size(), 0);
236}
237
238/** Tests if the FL modification is correctly decoded without arguments */
239BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_default)
240{
241 environment_setup env_setup;
242
244
245 BOOST_REQUIRE_EQUAL(queue.size(), 1);
246
247 auto mod = dynamic_cast<const fl_modification*>(&queue.top());
248
249 // The dynamic_cast returns nullptr if the argument doesn't match the type
250 BOOST_REQUIRE(mod != nullptr);
251
252 BOOST_CHECK(mod->get_horiz());
253 BOOST_CHECK(!mod->get_vert());
254}
255
256/** Tests if the FL modification is correctly decoded with the horiz argument */
257BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_horiz)
258{
259 environment_setup env_setup;
260
261 modification_queue queue = modification::decode("~FL(horiz)");
262
263 BOOST_REQUIRE_EQUAL(queue.size(), 1);
264
265 auto mod = dynamic_cast<const fl_modification*>(&queue.top());
266
267 // The dynamic_cast returns nullptr if the argument doesn't match the type
268 BOOST_REQUIRE(mod != nullptr);
269
270 BOOST_CHECK(mod->get_horiz());
271 BOOST_CHECK(!mod->get_vert());
272}
273
274/** Tests if the FL modification is correctly decoded with the vert argument */
275BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_vert)
276{
277 environment_setup env_setup;
278
279 modification_queue queue = modification::decode("~FL(vert)");
280
281 BOOST_REQUIRE_EQUAL(queue.size(), 1);
282
283 auto mod = dynamic_cast<const fl_modification*>(&queue.top());
284
285 // The dynamic_cast returns nullptr if the argument doesn't match the type
286 BOOST_REQUIRE(mod != nullptr);
287
288 BOOST_CHECK(!mod->get_horiz());
289 BOOST_CHECK(mod->get_vert());
290}
291
292/** Tests if the FL modification is correctly decoded with both horiz and vert */
293BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_horiz_and_vert)
294{
295 environment_setup env_setup;
296
297 modification_queue queue = modification::decode("~FL(horiz,vert)");
298
299 BOOST_REQUIRE_EQUAL(queue.size(), 1);
300
301 auto mod = dynamic_cast<const fl_modification*>(&queue.top());
302
303 // The dynamic_cast returns nullptr if the argument doesn't match the type
304 BOOST_REQUIRE(mod != nullptr);
305
306 BOOST_CHECK(mod->get_horiz());
307 BOOST_CHECK(mod->get_vert());
308}
309
310/** Tests if the GS modification is correctly decoded */
311BOOST_AUTO_TEST_CASE(test_gs_modification_decoding)
312{
313 environment_setup env_setup;
314
316
317 BOOST_REQUIRE(queue.size() == 1);
318
319 auto mod = dynamic_cast<const gs_modification*>(&queue.top());
320
321 // The dynamic_cast returns nullptr if the argument doesn't match the type
322 BOOST_CHECK(mod != nullptr);
323}
324
325/** Tests if the CROP modification without arguments is ignored */
326BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_no_args)
327{
328 environment_setup env_setup;
329
330 modification_queue queue = modification::decode("~CROP()");
331
332 BOOST_REQUIRE_EQUAL(queue.size(), 0);
333}
334
335/** Tests if the CROP modification is correctly decoded when given one argument */
336BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_1_arg)
337{
338 environment_setup env_setup;
339
340 modification_queue queue = modification::decode("~CROP(1)");
341
342 BOOST_REQUIRE_EQUAL(queue.size(), 1);
343
344 auto mod = dynamic_cast<const crop_modification*>(&queue.top());
345
346 // The dynamic_cast returns nullptr if the argument doesn't match the type
347 BOOST_REQUIRE(mod != nullptr);
348
349 const rect& slice = mod->get_slice();
350
351 BOOST_CHECK_EQUAL(slice.x, 1);
352 BOOST_CHECK_EQUAL(slice.y, 0);
353 BOOST_CHECK_EQUAL(slice.w, 0);
354 BOOST_CHECK_EQUAL(slice.h, 0);
355}
356
357/** Tests if the CROP modification is correctly decoded when given two args */
358BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_2_args)
359{
360 environment_setup env_setup;
361
362 modification_queue queue = modification::decode("~CROP(1,2)");
363
364 BOOST_REQUIRE_EQUAL(queue.size(), 1);
365
366 auto mod = dynamic_cast<const crop_modification*>(&queue.top());
367
368 // The dynamic_cast returns nullptr if the argument doesn't match the type
369 BOOST_REQUIRE(mod != nullptr);
370
371 const rect& slice = mod->get_slice();
372
373 BOOST_CHECK_EQUAL(slice.x, 1);
374 BOOST_CHECK_EQUAL(slice.y, 2);
375 BOOST_CHECK_EQUAL(slice.w, 0);
376 BOOST_CHECK_EQUAL(slice.h, 0);
377}
378
379/** Tests if the CROP modification is correctly decoded when given three args */
380BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_3_args)
381{
382 environment_setup env_setup;
383
384 modification_queue queue = modification::decode("~CROP(1,2,3)");
385
386 BOOST_REQUIRE_EQUAL(queue.size(), 1);
387
388 auto mod = dynamic_cast<const crop_modification*>(&queue.top());
389
390 // The dynamic_cast returns nullptr if the argument doesn't match the type
391 BOOST_REQUIRE(mod != nullptr);
392
393 const rect& slice = mod->get_slice();
394
395 BOOST_CHECK_EQUAL(slice.x, 1);
396 BOOST_CHECK_EQUAL(slice.y, 2);
397 BOOST_CHECK_EQUAL(slice.w, 3);
398 BOOST_CHECK_EQUAL(slice.h, 0);
399}
400
401/** Tests if the CROP modification is correctly decoded when given four args */
402BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_4_args)
403{
404 environment_setup env_setup;
405
406 modification_queue queue = modification::decode("~CROP(1,2,3,4)");
407
408 BOOST_REQUIRE_EQUAL(queue.size(), 1);
409
410 auto mod = dynamic_cast<const crop_modification*>(&queue.top());
411
412 // The dynamic_cast returns nullptr if the argument doesn't match the type
413 BOOST_REQUIRE(mod != nullptr);
414
415 const rect& slice = mod->get_slice();
416
417 BOOST_CHECK_EQUAL(slice.x, 1);
418 BOOST_CHECK_EQUAL(slice.y, 2);
419 BOOST_CHECK_EQUAL(slice.w, 3);
420 BOOST_CHECK_EQUAL(slice.h, 4);
421}
422
423/** Tests if the BLIT modification with one argument is correctly decoded
424 *
425 * @todo check if the surface is correct
426 */
427BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_1_arg)
428{
429 environment_setup env_setup;
430
431 modification_queue queue = modification::decode("~BLIT(wesnoth-icon.png)");
432
433 BOOST_REQUIRE_EQUAL(queue.size(), 1);
434
435 auto mod = dynamic_cast<const blit_modification*>(&queue.top());
436
437 // The dynamic_cast returns nullptr if the argument doesn't match the type
438 BOOST_REQUIRE(mod != nullptr);
439
440 BOOST_CHECK(mod->get_surface());
441 BOOST_CHECK_EQUAL(mod->get_x(), 0);
442 BOOST_CHECK_EQUAL(mod->get_y(), 0);
443}
444
445/** Tests if the BLIT modification with three arguments is correctly decoded
446 *
447 * @todo check if the surface is correct
448 */
449BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_3_args)
450{
451 environment_setup env_setup;
452
453 modification_queue queue = modification::decode("~BLIT(wesnoth-icon.png,1,2)");
454
455 BOOST_REQUIRE_EQUAL(queue.size(), 1);
456
457 auto mod = dynamic_cast<const blit_modification*>(&queue.top());
458
459 BOOST_REQUIRE(mod != nullptr);
460 // The dynamic_cast returns nullptr if the argument doesn't match the type
461
462 BOOST_CHECK(mod->get_surface());
463 BOOST_CHECK_EQUAL(mod->get_x(), 1);
464 BOOST_CHECK_EQUAL(mod->get_y(), 2);
465}
466
467/** Tests if the BLIT modification with invalid arguments is ignored */
468BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_invalid_args)
469{
470 environment_setup env_setup;
471
472 modification_queue queue =
473 modification::decode("~BLIT()"
474 "~BLIT(wesnoth-icon.png,1,-2)"
475 "~BLIT(wesnoth-icon.png,-1,2)"
476 "~BLIT(wesnoth-icon.png,-1,-2)"
477 "~BLIT(wesnoth-icon.png,1,2,3)");
478
479 BOOST_CHECK_EQUAL(queue.size(), 3);
480}
481
482/** Tests if the MASK modification with one argument is correctly decoded
483 *
484 * @todo check if the surface is correct
485 */
486BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_1_arg)
487{
488 environment_setup env_setup;
489
490 modification_queue queue = modification::decode("~MASK(wesnoth-icon.png)");
491
492 BOOST_REQUIRE_EQUAL(queue.size(), 1);
493
494 auto mod = dynamic_cast<const mask_modification*>(&queue.top());
495
496 // The dynamic_cast returns nullptr if the argument doesn't match the type
497 BOOST_REQUIRE(mod != nullptr);
498
499 BOOST_CHECK(mod->get_mask());
500 BOOST_CHECK_EQUAL(mod->get_x(), 0);
501 BOOST_CHECK_EQUAL(mod->get_y(), 0);
502}
503
504/** Tests if the MASK modification with three arguments is correctly decoded
505 *
506 * @todo check if the surface is correct
507 */
508BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_3_args)
509{
510 environment_setup env_setup;
511
512 modification_queue queue = modification::decode("~MASK(wesnoth-icon.png,3,4)");
513
514 BOOST_REQUIRE_EQUAL(queue.size(), 1);
515
516 auto mod = dynamic_cast<const mask_modification*>(&queue.top());
517
518 // The dynamic_cast returns nullptr if the argument doesn't match the type
519 BOOST_REQUIRE(mod != nullptr);
520
521 BOOST_CHECK(mod->get_mask());
522 BOOST_CHECK_EQUAL(mod->get_x(), 3);
523 BOOST_CHECK_EQUAL(mod->get_y(), 4);
524}
525
526/** Tests if the MASK modification with invalid arguments is ignored */
527BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_invalid_args)
528{
529 environment_setup env_setup;
530
531 modification_queue queue =
532 modification::decode("~MASK()"
533 "~MASK(wesnoth-icon.png,3,-4)"
534 "~MASK(wesnoth-icon.png,-3,4)"
535 "~MASK(wesnoth-icon.png,-3,-4)");
536
537 BOOST_CHECK_EQUAL(queue.size(), 0);
538}
539
540/** Tests if the L modification without arguments is ignored */
541BOOST_AUTO_TEST_CASE(test_l_modification_decoding_no_args)
542{
543 environment_setup env_setup;
544
546
547 BOOST_CHECK_EQUAL(queue.size(), 0);
548}
549
550/** Tests if the L modification with one argument is correctly decoded
551 *
552 * @todo check if the surface is correct
553 */
554BOOST_AUTO_TEST_CASE(test_l_modification_decoding_1_arg)
555{
556 environment_setup env_setup;
557
558 modification_queue queue = modification::decode("~L(wesnoth-icon.png)");
559
560 BOOST_REQUIRE_EQUAL(queue.size(), 1);
561
562 auto mod = dynamic_cast<const light_modification*>(&queue.top());
563
564 // The dynamic_cast returns nullptr if the argument doesn't match the type
565 BOOST_REQUIRE(mod != nullptr);
566
567 BOOST_CHECK(mod->get_surface());
568}
569
570/** Tests if the SCALE modification without arguments is ignored */
571BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_no_args)
572{
573 environment_setup env_setup;
574
575 modification_queue queue = modification::decode("~SCALE()");
576
577 BOOST_CHECK_EQUAL(queue.size(), 0);
578}
579
580/** Tests if the SCALE modification with one argument is correctly decoded */
581BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_1_arg)
582{
583 environment_setup env_setup;
584
585 modification_queue queue = modification::decode("~SCALE(3)");
586
587 BOOST_REQUIRE_EQUAL(queue.size(), 1);
588
589 auto mod = dynamic_cast<const scale_modification*>(&queue.top());
590
591 // The dynamic_cast returns nullptr if the argument doesn't match the type
592 BOOST_REQUIRE(mod != nullptr);
593
594 BOOST_CHECK_EQUAL(mod->get_w(), 3);
595 BOOST_CHECK_EQUAL(mod->get_h(), 0);
596}
597
598/** Tests if the SCALE modification with two arguments is correctly decoded */
599BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_2_args)
600{
601 environment_setup env_setup;
602
603 modification_queue queue = modification::decode("~SCALE(4,5)");
604
605 BOOST_REQUIRE_EQUAL(queue.size(), 1);
606
607 auto mod = dynamic_cast<const scale_modification*>(&queue.top());
608
609 // The dynamic_cast returns nullptr if the argument doesn't match the type
610 BOOST_REQUIRE(mod != nullptr);
611
612 BOOST_CHECK_EQUAL(mod->get_w(), 4);
613 BOOST_CHECK_EQUAL(mod->get_h(), 5);
614}
615
616/** Tests if the O modification with a percent argument is correctly decoded */
617BOOST_AUTO_TEST_CASE(test_o_modification_decoding_percent_args)
618{
619 environment_setup env_setup;
620
621 modification_queue queue = modification::decode("~O(45%)");
622
623 BOOST_REQUIRE_EQUAL(queue.size(), 1);
624
625 auto mod = dynamic_cast<const o_modification*>(&queue.top());
626
627 // The dynamic_cast returns nullptr if the argument doesn't match the type
628 BOOST_REQUIRE(mod != nullptr);
629
630 BOOST_CHECK(mod->get_opacity() > 0.44f);
631 BOOST_CHECK(mod->get_opacity() < 0.46f);
632}
633
634/** Tests if the O modification with a fraction argument is correctly decoded */
635BOOST_AUTO_TEST_CASE(test_o_modification_decoding_fraction_args)
636{
637 environment_setup env_setup;
638
639 modification_queue queue = modification::decode("~O(0.34)");
640
641 BOOST_REQUIRE_EQUAL(queue.size(), 1);
642
643 auto mod = dynamic_cast<const o_modification*>(&queue.top());
644
645 // The dynamic_cast returns nullptr if the argument doesn't match the type
646 BOOST_REQUIRE(mod != nullptr);
647
648 BOOST_CHECK(mod->get_opacity() > 0.33f);
649 BOOST_CHECK(mod->get_opacity() < 0.35f);
650}
651
652/** Tests if the BL modification without arguments is correctly decoded */
653BOOST_AUTO_TEST_CASE(test_bl_modification_decoding_no_args)
654{
655 environment_setup env_setup;
656
658
659 BOOST_REQUIRE_EQUAL(queue.size(), 1);
660
661 auto mod = dynamic_cast<const bl_modification*>(&queue.top());
662
663 // The dynamic_cast returns nullptr if the argument doesn't match the type
664 BOOST_REQUIRE(mod != nullptr);
665
666 BOOST_CHECK_EQUAL(mod->get_depth(), 0);
667}
668
669/** Tests if the BL modification with one argument is correctly decoded */
670BOOST_AUTO_TEST_CASE(test_bl_modification_decoding)
671{
672 environment_setup env_setup;
673
675
676 BOOST_REQUIRE_EQUAL(queue.size(), 1);
677
678 auto mod = dynamic_cast<const bl_modification*>(&queue.top());
679
680 // The dynamic_cast returns nullptr if the argument doesn't match the type
681 BOOST_REQUIRE(mod != nullptr);
682
683 BOOST_CHECK_EQUAL(mod->get_depth(), 2);
684}
685
686/** Tests if the R, G and B modifications without args are correctly decoded */
687BOOST_AUTO_TEST_CASE(test_rgb_modification_decoding_no_args)
688{
689 environment_setup env_setup;
690
691 modification_queue queue = modification::decode("~R()~G()~B()");
692
693 BOOST_REQUIRE_EQUAL(queue.size(), 3);
694
695 for(int i = 0; i < 3; i++) {
696 environment_setup env_setup;
697
698 auto mod = dynamic_cast<const cs_modification*>(&queue.top());
699
700 // The dynamic_cast returns nullptr if the argument doesn't match the type
701 BOOST_REQUIRE(mod != nullptr);
702
703 BOOST_CHECK_EQUAL(mod->get_r(), 0);
704 BOOST_CHECK_EQUAL(mod->get_g(), 0);
705 BOOST_CHECK_EQUAL(mod->get_b(), 0);
706
707 queue.pop();
708 }
709}
710
711/** Tests if the R modification with one argument is correctly decoded */
712BOOST_AUTO_TEST_CASE(test_r_modification_decoding)
713{
714 environment_setup env_setup;
715
716 modification_queue queue = modification::decode("~R(123)");
717
718 BOOST_REQUIRE_EQUAL(queue.size(), 1);
719
720 auto mod = dynamic_cast<const cs_modification*>(&queue.top());
721
722 // The dynamic_cast returns nullptr if the argument doesn't match the type
723 BOOST_REQUIRE(mod != nullptr);
724
725 BOOST_CHECK_EQUAL(mod->get_r(), 123);
726 BOOST_CHECK_EQUAL(mod->get_g(), 0);
727 BOOST_CHECK_EQUAL(mod->get_b(), 0);
728}
729
730/** Tests if the G modification with one argument is correctly decoded */
731BOOST_AUTO_TEST_CASE(test_g_modification_decoding)
732{
733 environment_setup env_setup;
734
735 modification_queue queue = modification::decode("~G(132)");
736
737 BOOST_REQUIRE_EQUAL(queue.size(), 1);
738
739 auto mod = dynamic_cast<const cs_modification*>(&queue.top());
740
741 // The dynamic_cast returns nullptr if the argument doesn't match the type
742 BOOST_REQUIRE(mod != nullptr);
743
744 BOOST_CHECK_EQUAL(mod->get_r(), 0);
745 BOOST_CHECK_EQUAL(mod->get_g(), 132);
746 BOOST_CHECK_EQUAL(mod->get_b(), 0);
747}
748
749/** Tests if the B modification with one argument is correctly decoded */
750BOOST_AUTO_TEST_CASE(test_b_modification_decoding)
751{
752 environment_setup env_setup;
753
754 modification_queue queue = modification::decode("~B(312)");
755
756 BOOST_REQUIRE_EQUAL(queue.size(), 1);
757
758 auto mod = dynamic_cast<const cs_modification*>(&queue.top());
759
760 // The dynamic_cast returns nullptr if the argument doesn't match the type
761 BOOST_REQUIRE(mod != nullptr);
762
763 BOOST_CHECK_EQUAL(mod->get_r(), 0);
764 BOOST_CHECK_EQUAL(mod->get_g(), 0);
765 BOOST_CHECK_EQUAL(mod->get_b(), 312);
766}
767
768/** Tests if the BG modification without arguments is correctly decoded */
769BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_no_args)
770{
771 environment_setup env_setup;
772
774
775 BOOST_REQUIRE_EQUAL(queue.size(), 1);
776
777 auto mod = dynamic_cast<const background_modification*>(&queue.top());
778
779 // The dynamic_cast returns nullptr if the argument doesn't match the type
780 BOOST_REQUIRE(mod != nullptr);
781
782 BOOST_CHECK_EQUAL(mod->get_color().r, 0);
783 BOOST_CHECK_EQUAL(mod->get_color().g, 0);
784 BOOST_CHECK_EQUAL(mod->get_color().b, 0);
785 BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
786}
787
788/** Tests if the BG modification with one argument is correctly decoded */
789BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_1_arg)
790{
791 environment_setup env_setup;
792
794
795 BOOST_REQUIRE_EQUAL(queue.size(), 1);
796
797 auto mod = dynamic_cast<const background_modification*>(&queue.top());
798
799 // The dynamic_cast returns nullptr if the argument doesn't match the type
800 BOOST_REQUIRE(mod != nullptr);
801
802 BOOST_CHECK_EQUAL(mod->get_color().r, 1);
803 BOOST_CHECK_EQUAL(mod->get_color().g, 0);
804 BOOST_CHECK_EQUAL(mod->get_color().b, 0);
805 BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
806}
807
808/** Tests if the BG modification with two arguments is correctly decoded */
809BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_2_args)
810{
811 environment_setup env_setup;
812
813 modification_queue queue = modification::decode("~BG(1,2)");
814
815 BOOST_REQUIRE_EQUAL(queue.size(), 1);
816
817 auto mod = dynamic_cast<const background_modification*>(&queue.top());
818
819 // The dynamic_cast returns nullptr if the argument doesn't match the type
820 BOOST_REQUIRE(mod != nullptr);
821
822 BOOST_CHECK_EQUAL(mod->get_color().r, 1);
823 BOOST_CHECK_EQUAL(mod->get_color().g, 2);
824 BOOST_CHECK_EQUAL(mod->get_color().b, 0);
825 BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
826}
827
828/** Tests if the BG modification with three arguments is correctly decoded */
829BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_3_args)
830{
831 environment_setup env_setup;
832
833 modification_queue queue = modification::decode("~BG(1,2,3)");
834
835 BOOST_REQUIRE_EQUAL(queue.size(), 1);
836
837 auto mod = dynamic_cast<const background_modification*>(&queue.top());
838
839 // The dynamic_cast returns nullptr if the argument doesn't match the type
840 BOOST_REQUIRE(mod != nullptr);
841
842 BOOST_CHECK_EQUAL(mod->get_color().r, 1);
843 BOOST_CHECK_EQUAL(mod->get_color().g, 2);
844 BOOST_CHECK_EQUAL(mod->get_color().b, 3);
845 BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
846}
847
848/** Tests if the BG modification with four arguments is correctly decoded */
849BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_4_args)
850{
851 environment_setup env_setup;
852
853 modification_queue queue = modification::decode("~BG(1,2,3,4)");
854
855 BOOST_REQUIRE_EQUAL(queue.size(), 1);
856
857 auto mod = dynamic_cast<const background_modification*>(&queue.top());
858
859 // The dynamic_cast returns nullptr if the argument doesn't match the type
860 BOOST_REQUIRE(mod != nullptr);
861
862 BOOST_CHECK_EQUAL(mod->get_color().r, 1);
863 BOOST_CHECK_EQUAL(mod->get_color().g, 2);
864 BOOST_CHECK_EQUAL(mod->get_color().b, 3);
865 BOOST_CHECK_EQUAL(mod->get_color().a, 4);
866}
867
868BOOST_AUTO_TEST_SUITE_END()
Representing the "team color" information, this C++ class contains a subset of WML's [color_range] ta...
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
static game_config_view wrap(const config &cfg)
Gaussian-like blur (BL) modification.
Scale (BLIT) modification.
Crop (CROP) modification.
Color-shift (CS, R, G, B) modification.
Mirror (FL) modification.
Grayscale (GS) modification.
Mask (MASK) modification.
A modified priority queue used to order image modifications.
void push(std::unique_ptr< modification > &&mod)
Adds mod to the queue.
const modification & top() const
Returns a const reference to the top element in the queue.
void pop()
Removes the top element from the queue.
std::size_t size() const
Returns the number of elements in the queue.
Base abstract class for an image-path modification.
static modification_queue decode(const std::string &)
Decodes modifications from a modification string.
Opacity (O) modification.
Recolor (RC/TC/PAL) modification.
Scaling (SCALE[_INTO], SCALE[_INTO]_SHARP) modifications.
Helper class to redirect the output of the logger in a certain scope.
Definition log.hpp:98
color_mapping generate_color_mapping(const color_range &new_range, const std::vector< color_t > &old_rgb)
Converts a source palette using the specified color_range object.
std::unordered_map< color_t, color_t > color_mapping
Definitions for the interface to Wesnoth Markup Language (WML).
const config * cfg
Declarations for File-IO.
Standard logging facilities (interface).
const std::vector< color_t > & tc_info(std::string_view name)
const color_range & color_info(std::string_view name)
static void add_color_info(const game_config_view &v, bool build_defaults)
Functions to load and save images from/to disk.
The paths manager is responsible for recording the various paths that binary files may be located at.
Fill background with a color (BG).
An abstract description of a rectangle with integer coordinates.
Definition rect.hpp:49
BOOST_AUTO_TEST_SUITE(filesystem)
BOOST_AUTO_TEST_CASE(test_modificaiton_queue_order)
Tests if modifications with a higher priority are placed before the others.
#define i