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