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