The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
test_image_modifications.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2011 - 2016 by Karol Kozub <[email protected]>
3  Part of the Battle for Wesnoth Project http://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 "image.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  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  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  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::tredirect_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  // reverse insertion order now
151  queue.push(high_priority_mod);
152  queue.push(low_priority_mod);
153 
154  BOOST_REQUIRE_EQUAL(queue.size(), 2);
155 
156  BOOST_CHECK_EQUAL(queue.top(), high_priority_mod);
157  queue.pop();
158  BOOST_CHECK_EQUAL(queue.top(), low_priority_mod);
159  queue.pop();
160 
161  delete low_priority_mod;
162  delete high_priority_mod;
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<Uint32>& 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  std::map<Uint32, Uint32> expected = recolor_range(new_color, old_color);
183 
184  BOOST_CHECK(expected == mod->map());
185 
186  delete mod;
187 }
188 
189 /// Tests if the TC modification with invalid arguments is ignored
190 BOOST_AUTO_TEST_CASE(test_tc_modification_decoding_invalid_args)
191 {
192  environment_setup env_setup;
193 
194  modification_queue queue = modification::decode("~TC()~TC(1)~TC(0,blue)");
195 
196  BOOST_REQUIRE_EQUAL(queue.size(), 0);
197 }
198 
199 /// Tests if the RC modification is correctly decoded
200 BOOST_AUTO_TEST_CASE(test_rc_modification_decoding)
201 {
202  environment_setup env_setup;
203 
204  modification_queue queue = modification::decode("~RC(red>blue)");
205 
206  BOOST_REQUIRE_EQUAL(queue.size(), 1);
207 
208  rc_modification* mod = dynamic_cast<rc_modification*>(queue.top());
209 
210  // The dynamic_cast returns nullptr if the argument doesn't match the type
211  BOOST_REQUIRE(mod != nullptr);
212 
213  const std::vector<Uint32>& old_color = game_config::tc_info("red");
214  const color_range& new_color = game_config::color_info("blue");
215  std::map<Uint32, Uint32> expected = recolor_range(new_color, old_color);
216 
217  BOOST_CHECK(expected == mod->map());
218 
219  delete mod;
220 }
221 
222 /// Tests if the RC modification with invalid arguments is ignored
223 BOOST_AUTO_TEST_CASE(test_rc_modification_decoding_invalid_args)
224 {
225  environment_setup env_setup;
226 
227  modification_queue queue = modification::decode("~RC()~RC(blue)~RC(>)");
228 
229  BOOST_REQUIRE_EQUAL(queue.size(), 0);
230 }
231 
232 /// Tests if the PAL modification is correctly decoded
233 BOOST_AUTO_TEST_CASE(test_pal_modification_decoding)
234 {
235  environment_setup env_setup;
236 
237  modification_queue queue =
238  modification::decode("~PAL(000000,005000 > FFFFFF,FF00FF)");
239 
240  BOOST_REQUIRE_EQUAL(queue.size(), 1);
241 
242  rc_modification* mod = dynamic_cast<rc_modification*>(queue.top());
243 
244  // The dynamic_cast returns nullptr if the argument doesn't match the type
245  BOOST_REQUIRE(mod != nullptr);
246 
247  std::vector<Uint32> const& old_palette = game_config::tc_info("000000,005000");
248  std::vector<Uint32> const& new_palette = game_config::tc_info("FFFFFF,FF00FF");
249  std::map<Uint32, Uint32> expected;
250 
251  for(size_t i = 0; i < old_palette.size() && i < new_palette.size(); ++i) {
252  environment_setup env_setup;
253 
254  expected[old_palette[i]] = new_palette[i];
255  }
256 
257  BOOST_CHECK(expected == mod->map());
258 
259  delete mod;
260 }
261 
262 /// Tests if the PAL modification with invalid arguments is ignored
263 BOOST_AUTO_TEST_CASE(test_pal_modification_decoding_invalid_args)
264 {
265  environment_setup env_setup;
266 
267  modification_queue queue =
268  modification::decode("~PAL()~PAL(>)");
269 
270  BOOST_REQUIRE_EQUAL(queue.size(), 0);
271 }
272 
273 /// Tests if the FL modification is correctly decoded without arguments
274 BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_default)
275 {
276  environment_setup env_setup;
277 
278  modification_queue queue = modification::decode("~FL()");
279 
280  BOOST_REQUIRE_EQUAL(queue.size(), 1);
281 
282  fl_modification* mod = dynamic_cast<fl_modification*>(queue.top());
283 
284  // The dynamic_cast returns nullptr if the argument doesn't match the type
285  BOOST_REQUIRE(mod != nullptr);
286 
287  BOOST_CHECK(mod->get_horiz());
288  BOOST_CHECK(!mod->get_vert());
289 
290  delete mod;
291 }
292 
293 /// Tests if the FL modification is correctly decoded with the horiz argument
294 BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_horiz)
295 {
296  environment_setup env_setup;
297 
298  modification_queue queue = modification::decode("~FL(horiz)");
299 
300  BOOST_REQUIRE_EQUAL(queue.size(), 1);
301 
302  fl_modification* mod = dynamic_cast<fl_modification*>(queue.top());
303 
304  // The dynamic_cast returns nullptr if the argument doesn't match the type
305  BOOST_REQUIRE(mod != nullptr);
306 
307  BOOST_CHECK(mod->get_horiz());
308  BOOST_CHECK(!mod->get_vert());
309 
310  delete mod;
311 }
312 
313 /// Tests if the FL modification is correctly decoded with the vert argument
314 BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_vert)
315 {
316  environment_setup env_setup;
317 
318  modification_queue queue = modification::decode("~FL(vert)");
319 
320  BOOST_REQUIRE_EQUAL(queue.size(), 1);
321 
322  fl_modification* mod = dynamic_cast<fl_modification*>(queue.top());
323 
324  // The dynamic_cast returns nullptr if the argument doesn't match the type
325  BOOST_REQUIRE(mod != nullptr);
326 
327  BOOST_CHECK(!mod->get_horiz());
328  BOOST_CHECK(mod->get_vert());
329 
330  delete mod;
331 }
332 
333 /// Tests if the FL modification is correctly decoded with both horiz and vert
334 BOOST_AUTO_TEST_CASE(test_fl_modification_decoding_horiz_and_vert)
335 {
336  environment_setup env_setup;
337 
338  modification_queue queue = modification::decode("~FL(horiz,vert)");
339 
340  BOOST_REQUIRE_EQUAL(queue.size(), 1);
341 
342  fl_modification* mod = dynamic_cast<fl_modification*>(queue.top());
343 
344  // The dynamic_cast returns nullptr if the argument doesn't match the type
345  BOOST_REQUIRE(mod != nullptr);
346 
347  BOOST_CHECK(mod->get_horiz());
348  BOOST_CHECK(mod->get_vert());
349 
350  delete mod;
351 }
352 
353 /// Tests if the GS modification is correctly decoded
354 BOOST_AUTO_TEST_CASE(test_gs_modification_decoding)
355 {
356  environment_setup env_setup;
357 
358  modification_queue queue = modification::decode("~GS()");
359 
360  BOOST_REQUIRE(queue.size() == 1);
361 
362  gs_modification* mod = dynamic_cast<gs_modification*>(queue.top());
363 
364  // The dynamic_cast returns nullptr if the argument doesn't match the type
365  BOOST_CHECK(mod != nullptr);
366 
367  delete mod;
368 }
369 
370 /// Tests if the CROP modification without arguments is ignored
371 BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_no_args)
372 {
373  environment_setup env_setup;
374 
375  modification_queue queue = modification::decode("~CROP()");
376 
377  BOOST_REQUIRE_EQUAL(queue.size(), 0);
378 }
379 
380 /// Tests if the CROP modification is correctly decoded when given one argument
381 BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_1_arg)
382 {
383  environment_setup env_setup;
384 
385  modification_queue queue = modification::decode("~CROP(1)");
386 
387  BOOST_REQUIRE_EQUAL(queue.size(), 1);
388 
389  crop_modification* mod = dynamic_cast<crop_modification*>(queue.top());
390 
391  // The dynamic_cast returns nullptr if the argument doesn't match the type
392  BOOST_REQUIRE(mod != nullptr);
393 
394  const SDL_Rect& slice = mod->get_slice();
395 
396  BOOST_CHECK_EQUAL(slice.x, 1);
397  BOOST_CHECK_EQUAL(slice.y, 0);
398  BOOST_CHECK_EQUAL(slice.w, 0);
399  BOOST_CHECK_EQUAL(slice.h, 0);
400 
401  delete mod;
402 }
403 
404 /// Tests if the CROP modification is correctly decoded when given two args
405 BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_2_args)
406 {
407  environment_setup env_setup;
408 
409  modification_queue queue = modification::decode("~CROP(1,2)");
410 
411  BOOST_REQUIRE_EQUAL(queue.size(), 1);
412 
413  crop_modification* mod = dynamic_cast<crop_modification*>(queue.top());
414 
415  // The dynamic_cast returns nullptr if the argument doesn't match the type
416  BOOST_REQUIRE(mod != nullptr);
417 
418  const SDL_Rect& slice = mod->get_slice();
419 
420  BOOST_CHECK_EQUAL(slice.x, 1);
421  BOOST_CHECK_EQUAL(slice.y, 2);
422  BOOST_CHECK_EQUAL(slice.w, 0);
423  BOOST_CHECK_EQUAL(slice.h, 0);
424 
425  delete mod;
426 }
427 
428 /// Tests if the CROP modification is correctly decoded when given three args
429 BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_3_args)
430 {
431  environment_setup env_setup;
432 
433  modification_queue queue = modification::decode("~CROP(1,2,3)");
434 
435  BOOST_REQUIRE_EQUAL(queue.size(), 1);
436 
437  crop_modification* mod = dynamic_cast<crop_modification*>(queue.top());
438 
439  // The dynamic_cast returns nullptr if the argument doesn't match the type
440  BOOST_REQUIRE(mod != nullptr);
441 
442  const SDL_Rect& slice = mod->get_slice();
443 
444  BOOST_CHECK_EQUAL(slice.x, 1);
445  BOOST_CHECK_EQUAL(slice.y, 2);
446  BOOST_CHECK_EQUAL(slice.w, 3);
447  BOOST_CHECK_EQUAL(slice.h, 0);
448 
449  delete mod;
450 }
451 
452 /// Tests if the CROP modification is correctly decoded when given four args
453 BOOST_AUTO_TEST_CASE(test_crop_modification_decoding_4_args)
454 {
455  environment_setup env_setup;
456 
457  modification_queue queue = modification::decode("~CROP(1,2,3,4)");
458 
459  BOOST_REQUIRE_EQUAL(queue.size(), 1);
460 
461  crop_modification* mod = dynamic_cast<crop_modification*>(queue.top());
462 
463  // The dynamic_cast returns nullptr if the argument doesn't match the type
464  BOOST_REQUIRE(mod != nullptr);
465 
466  const SDL_Rect& slice = mod->get_slice();
467 
468  BOOST_CHECK_EQUAL(slice.x, 1);
469  BOOST_CHECK_EQUAL(slice.y, 2);
470  BOOST_CHECK_EQUAL(slice.w, 3);
471  BOOST_CHECK_EQUAL(slice.h, 4);
472 
473  delete mod;
474 }
475 
476 /** Tests if the BLIT modification with one argument is correctly decoded
477  *
478  * @todo check if the surface is correct
479  */
480 BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_1_arg)
481 {
482  environment_setup env_setup;
483 
484  modification_queue queue = modification::decode("~BLIT(wesnoth-icon.png)");
485 
486  BOOST_REQUIRE_EQUAL(queue.size(), 1);
487 
488  blit_modification* mod = dynamic_cast<blit_modification*>(queue.top());
489 
490  // The dynamic_cast returns nullptr if the argument doesn't match the type
491  BOOST_REQUIRE(mod != nullptr);
492 
493  BOOST_CHECK(!mod->get_surface().null());
494  BOOST_CHECK_EQUAL(mod->get_x(), 0);
495  BOOST_CHECK_EQUAL(mod->get_y(), 0);
496 
497  delete mod;
498 }
499 
500 /** Tests if the BLIT modification with three arguments is correctly decoded
501  *
502  * @todo check if the surface is correct
503  */
504 BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_3_args)
505 {
506  environment_setup env_setup;
507 
508  modification_queue queue = modification::decode("~BLIT(wesnoth-icon.png,1,2)");
509 
510  BOOST_REQUIRE_EQUAL(queue.size(), 1);
511 
512  blit_modification* mod = dynamic_cast<blit_modification*>(queue.top());
513 
514  BOOST_REQUIRE(mod != nullptr);
515  // The dynamic_cast returns nullptr if the argument doesn't match the type
516 
517  BOOST_CHECK(!mod->get_surface().null());
518  BOOST_CHECK_EQUAL(mod->get_x(), 1);
519  BOOST_CHECK_EQUAL(mod->get_y(), 2);
520 
521  delete mod;
522 }
523 
524 /// Tests if the BLIT modification with invalid arguments is ignored
525 BOOST_AUTO_TEST_CASE(test_blit_modification_decoding_invalid_args)
526 {
527  environment_setup env_setup;
528 
529  modification_queue queue =
530  modification::decode("~BLIT()"
531  "~BLIT(wesnoth-icon.png,1,-2)"
532  "~BLIT(wesnoth-icon.png,-1,2)"
533  "~BLIT(wesnoth-icon.png,-1,-2)");
534 
535  BOOST_CHECK_EQUAL(queue.size(), 0);
536 }
537 
538 /** Tests if the MASK modification with one argument is correctly decoded
539  *
540  * @todo check if the surface is correct
541  */
542 BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_1_arg)
543 {
544  environment_setup env_setup;
545 
546  modification_queue queue = modification::decode("~MASK(wesnoth-icon.png)");
547 
548  BOOST_REQUIRE_EQUAL(queue.size(), 1);
549 
550  mask_modification* mod = dynamic_cast<mask_modification*>(queue.top());
551 
552  // The dynamic_cast returns nullptr if the argument doesn't match the type
553  BOOST_REQUIRE(mod != nullptr);
554 
555  BOOST_CHECK(!mod->get_mask().null());
556  BOOST_CHECK_EQUAL(mod->get_x(), 0);
557  BOOST_CHECK_EQUAL(mod->get_y(), 0);
558 
559  delete mod;
560 }
561 
562 /** Tests if the MASK modification with three arguments is correctly decoded
563  *
564  * @todo check if the surface is correct
565  */
566 BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_3_args)
567 {
568  environment_setup env_setup;
569 
570  modification_queue queue = modification::decode("~MASK(wesnoth-icon.png,3,4)");
571 
572  BOOST_REQUIRE_EQUAL(queue.size(), 1);
573 
574  mask_modification* mod = dynamic_cast<mask_modification*>(queue.top());
575 
576  // The dynamic_cast returns nullptr if the argument doesn't match the type
577  BOOST_REQUIRE(mod != nullptr);
578 
579  BOOST_CHECK(!mod->get_mask().null());
580  BOOST_CHECK_EQUAL(mod->get_x(), 3);
581  BOOST_CHECK_EQUAL(mod->get_y(), 4);
582 
583  delete mod;
584 }
585 
586 /// Tests if the MASK modification with invalid arguments is ignored
587 BOOST_AUTO_TEST_CASE(test_mask_modification_decoding_invalid_args)
588 {
589  environment_setup env_setup;
590 
591  modification_queue queue =
592  modification::decode("~MASK()"
593  "~MASK(wesnoth-icon.png,3,-4)"
594  "~MASK(wesnoth-icon.png,-3,4)"
595  "~MASK(wesnoth-icon.png,-3,-4)");
596 
597  BOOST_CHECK_EQUAL(queue.size(), 0);
598 }
599 
600 /// Tests if the L modification without arguments is ignored
601 BOOST_AUTO_TEST_CASE(test_l_modification_decoding_no_args)
602 {
603  environment_setup env_setup;
604 
606 
607  BOOST_CHECK_EQUAL(queue.size(), 0);
608 }
609 
610 /** Tests if the L modification with one argument is correctly decoded
611  *
612  * @todo check if the surface is correct
613  */
614 BOOST_AUTO_TEST_CASE(test_l_modification_decoding_1_arg)
615 {
616  environment_setup env_setup;
617 
618  modification_queue queue = modification::decode("~L(wesnoth-icon.png)");
619 
620  BOOST_REQUIRE_EQUAL(queue.size(), 1);
621 
622  light_modification* mod = dynamic_cast<light_modification*>(queue.top());
623 
624  // The dynamic_cast returns nullptr if the argument doesn't match the type
625  BOOST_REQUIRE(mod != nullptr);
626 
627  BOOST_CHECK(!mod->get_surface().null());
628 
629  delete mod;
630 }
631 
632 /// Tests if the SCALE modification without arguments is ignored
633 BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_no_args)
634 {
635  environment_setup env_setup;
636 
637  modification_queue queue = modification::decode("~SCALE()");
638 
639  BOOST_CHECK_EQUAL(queue.size(), 0);
640 }
641 
642 /// Tests if the SCALE modification with one argument is correctly decoded
643 BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_1_arg)
644 {
645  environment_setup env_setup;
646 
647  modification_queue queue = modification::decode("~SCALE(3)");
648 
649  BOOST_REQUIRE_EQUAL(queue.size(), 1);
650 
651  scale_modification* mod = dynamic_cast<scale_modification*>(queue.top());
652 
653  // The dynamic_cast returns nullptr if the argument doesn't match the type
654  BOOST_REQUIRE(mod != nullptr);
655 
656  BOOST_CHECK_EQUAL(mod->get_w(), 3);
657  BOOST_CHECK_EQUAL(mod->get_h(), 0);
658 
659  delete mod;
660 }
661 
662 /// Tests if the SCALE modification with two arguments is correctly decoded
663 BOOST_AUTO_TEST_CASE(test_scale_modification_decoding_2_args)
664 {
665  environment_setup env_setup;
666 
667  modification_queue queue = modification::decode("~SCALE(4,5)");
668 
669  BOOST_REQUIRE_EQUAL(queue.size(), 1);
670 
671  scale_modification* mod = dynamic_cast<scale_modification*>(queue.top());
672 
673  // The dynamic_cast returns nullptr if the argument doesn't match the type
674  BOOST_REQUIRE(mod != nullptr);
675 
676  BOOST_CHECK_EQUAL(mod->get_w(), 4);
677  BOOST_CHECK_EQUAL(mod->get_h(), 5);
678 
679  delete mod;
680 }
681 
682 /// Tests if the O modification with a percent argument is correctly decoded
683 BOOST_AUTO_TEST_CASE(test_o_modification_decoding_percent_args)
684 {
685  environment_setup env_setup;
686 
687  modification_queue queue = modification::decode("~O(45%)");
688 
689  BOOST_REQUIRE_EQUAL(queue.size(), 1);
690 
691  o_modification* mod = dynamic_cast<o_modification*>(queue.top());
692 
693  // The dynamic_cast returns nullptr if the argument doesn't match the type
694  BOOST_REQUIRE(mod != nullptr);
695 
696  BOOST_CHECK(mod->get_opacity() > 0.44f);
697  BOOST_CHECK(mod->get_opacity() < 0.46f);
698 
699  delete mod;
700 }
701 
702 /// Tests if the O modification with a fraction argument is correctly decoded
703 BOOST_AUTO_TEST_CASE(test_o_modification_decoding_fraction_args)
704 {
705  environment_setup env_setup;
706 
707  modification_queue queue = modification::decode("~O(0.34)");
708 
709  BOOST_REQUIRE_EQUAL(queue.size(), 1);
710 
711  o_modification* mod = dynamic_cast<o_modification*>(queue.top());
712 
713  // The dynamic_cast returns nullptr if the argument doesn't match the type
714  BOOST_REQUIRE(mod != nullptr);
715 
716  BOOST_CHECK(mod->get_opacity() > 0.33f);
717  BOOST_CHECK(mod->get_opacity() < 0.35f);
718 
719  delete mod;
720 }
721 
722 /// Tests if the BL modification without arguments is correctly decoded
723 BOOST_AUTO_TEST_CASE(test_bl_modification_decoding_no_args)
724 {
725  environment_setup env_setup;
726 
727  modification_queue queue = modification::decode("~BL()");
728 
729  BOOST_REQUIRE_EQUAL(queue.size(), 1);
730 
731  bl_modification* mod = dynamic_cast<bl_modification*>(queue.top());
732 
733  // The dynamic_cast returns nullptr if the argument doesn't match the type
734  BOOST_REQUIRE(mod != nullptr);
735 
736  BOOST_CHECK_EQUAL(mod->get_depth(), 0);
737 
738  delete mod;
739 }
740 
741 /// Tests if the BL modification with one argument is correctly decoded
742 BOOST_AUTO_TEST_CASE(test_bl_modification_decoding)
743 {
744  environment_setup env_setup;
745 
746  modification_queue queue = modification::decode("~BL(2)");
747 
748  BOOST_REQUIRE_EQUAL(queue.size(), 1);
749 
750  bl_modification* mod = dynamic_cast<bl_modification*>(queue.top());
751 
752  // The dynamic_cast returns nullptr if the argument doesn't match the type
753  BOOST_REQUIRE(mod != nullptr);
754 
755  BOOST_CHECK_EQUAL(mod->get_depth(), 2);
756 
757  delete mod;
758 }
759 
760 /// Tests if the R, G and B modifications without args are correctly decoded
761 BOOST_AUTO_TEST_CASE(test_rgb_modification_decoding_no_args)
762 {
763  environment_setup env_setup;
764 
765  modification_queue queue = modification::decode("~R()~G()~B()");
766 
767  BOOST_REQUIRE_EQUAL(queue.size(), 3);
768 
769  for(int i = 0; i < 3; i++) {
770  environment_setup env_setup;
771 
772  cs_modification* mod = dynamic_cast<cs_modification*>(queue.top());
773 
774  // The dynamic_cast returns nullptr if the argument doesn't match the type
775  BOOST_REQUIRE(mod != nullptr);
776 
777  BOOST_CHECK_EQUAL(mod->get_r(), 0);
778  BOOST_CHECK_EQUAL(mod->get_g(), 0);
779  BOOST_CHECK_EQUAL(mod->get_b(), 0);
780 
781  queue.pop();
782 
783  delete mod;
784  }
785 }
786 
787 /// Tests if the R modification with one argument is correctly decoded
788 BOOST_AUTO_TEST_CASE(test_r_modification_decoding)
789 {
790  environment_setup env_setup;
791 
792  modification_queue queue = modification::decode("~R(123)");
793 
794  BOOST_REQUIRE_EQUAL(queue.size(), 1);
795 
796  cs_modification* mod = dynamic_cast<cs_modification*>(queue.top());
797 
798  // The dynamic_cast returns nullptr if the argument doesn't match the type
799  BOOST_REQUIRE(mod != nullptr);
800 
801  BOOST_CHECK_EQUAL(mod->get_r(), 123);
802  BOOST_CHECK_EQUAL(mod->get_g(), 0);
803  BOOST_CHECK_EQUAL(mod->get_b(), 0);
804 
805  delete mod;
806 }
807 
808 /// Tests if the G modification with one argument is correctly decoded
809 BOOST_AUTO_TEST_CASE(test_g_modification_decoding)
810 {
811  environment_setup env_setup;
812 
813  modification_queue queue = modification::decode("~G(132)");
814 
815  BOOST_REQUIRE_EQUAL(queue.size(), 1);
816 
817  cs_modification* mod = dynamic_cast<cs_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_r(), 0);
823  BOOST_CHECK_EQUAL(mod->get_g(), 132);
824  BOOST_CHECK_EQUAL(mod->get_b(), 0);
825 
826  delete mod;
827 }
828 
829 /// Tests if the B modification with one argument is correctly decoded
830 BOOST_AUTO_TEST_CASE(test_b_modification_decoding)
831 {
832  environment_setup env_setup;
833 
834  modification_queue queue = modification::decode("~B(312)");
835 
836  BOOST_REQUIRE_EQUAL(queue.size(), 1);
837 
838  cs_modification* mod = dynamic_cast<cs_modification*>(queue.top());
839 
840  // The dynamic_cast returns nullptr if the argument doesn't match the type
841  BOOST_REQUIRE(mod != nullptr);
842 
843  BOOST_CHECK_EQUAL(mod->get_r(), 0);
844  BOOST_CHECK_EQUAL(mod->get_g(), 0);
845  BOOST_CHECK_EQUAL(mod->get_b(), 312);
846 
847  delete mod;
848 }
849 
850 /// Tests if the BRIGHTEN modification is correctly decoded
851 BOOST_AUTO_TEST_CASE(test_brighten_modification_decoding)
852 {
853  environment_setup env_setup;
854 
855  modification_queue queue = modification::decode("~BRIGHTEN()");
856 
857  BOOST_REQUIRE_EQUAL(queue.size(), 1);
858 
859  brighten_modification* mod = dynamic_cast<brighten_modification*>(queue.top());
860 
861  // The dynamic_cast returns nullptr if the argument doesn't match the type
862  BOOST_CHECK(mod != nullptr);
863 
864  delete mod;
865 }
866 
867 /// Tests if the DARKEN modification is correctly decoded
868 BOOST_AUTO_TEST_CASE(test_draken_modification_decoding)
869 {
870  environment_setup env_setup;
871 
872  modification_queue queue = modification::decode("~DARKEN()");
873 
874  BOOST_REQUIRE_EQUAL(queue.size(), 1);
875 
876  darken_modification* mod = dynamic_cast<darken_modification*>(queue.top());
877 
878  // The dynamic_cast returns nullptr if the argument doesn't match the type
879  BOOST_CHECK(mod != nullptr);
880 
881  delete mod;
882 }
883 
884 /// Tests if the BG modification without arguments is correctly decoded
885 BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_no_args)
886 {
887  environment_setup env_setup;
888 
889  modification_queue queue = modification::decode("~BG()");
890 
891  BOOST_REQUIRE_EQUAL(queue.size(), 1);
892 
893  background_modification* mod = dynamic_cast<background_modification*>(queue.top());
894 
895  // The dynamic_cast returns nullptr if the argument doesn't match the type
896  BOOST_REQUIRE(mod != nullptr);
897 
898  BOOST_CHECK_EQUAL(mod->get_color().r, 0);
899  BOOST_CHECK_EQUAL(mod->get_color().g, 0);
900  BOOST_CHECK_EQUAL(mod->get_color().b, 0);
901  BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
902 
903  delete mod;
904 }
905 
906 /// Tests if the BG modification with one argument is correctly decoded
907 BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_1_arg)
908 {
909  environment_setup env_setup;
910 
911  modification_queue queue = modification::decode("~BG(1)");
912 
913  BOOST_REQUIRE_EQUAL(queue.size(), 1);
914 
915  background_modification* mod = dynamic_cast<background_modification*>(queue.top());
916 
917  // The dynamic_cast returns nullptr if the argument doesn't match the type
918  BOOST_REQUIRE(mod != nullptr);
919 
920  BOOST_CHECK_EQUAL(mod->get_color().r, 1);
921  BOOST_CHECK_EQUAL(mod->get_color().g, 0);
922  BOOST_CHECK_EQUAL(mod->get_color().b, 0);
923  BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
924 
925  delete mod;
926 }
927 
928 /// Tests if the BG modification with two arguments is correctly decoded
929 BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_2_args)
930 {
931  environment_setup env_setup;
932 
933  modification_queue queue = modification::decode("~BG(1,2)");
934 
935  BOOST_REQUIRE_EQUAL(queue.size(), 1);
936 
937  background_modification* mod = dynamic_cast<background_modification*>(queue.top());
938 
939  // The dynamic_cast returns nullptr if the argument doesn't match the type
940  BOOST_REQUIRE(mod != nullptr);
941 
942  BOOST_CHECK_EQUAL(mod->get_color().r, 1);
943  BOOST_CHECK_EQUAL(mod->get_color().g, 2);
944  BOOST_CHECK_EQUAL(mod->get_color().b, 0);
945  BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
946 
947  delete mod;
948 }
949 
950 /// Tests if the BG modification with three arguments is correctly decoded
951 BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_3_args)
952 {
953  environment_setup env_setup;
954 
955  modification_queue queue = modification::decode("~BG(1,2,3)");
956 
957  BOOST_REQUIRE_EQUAL(queue.size(), 1);
958 
959  background_modification* mod = dynamic_cast<background_modification*>(queue.top());
960 
961  // The dynamic_cast returns nullptr if the argument doesn't match the type
962  BOOST_REQUIRE(mod != nullptr);
963 
964  BOOST_CHECK_EQUAL(mod->get_color().r, 1);
965  BOOST_CHECK_EQUAL(mod->get_color().g, 2);
966  BOOST_CHECK_EQUAL(mod->get_color().b, 3);
967  BOOST_CHECK_EQUAL(mod->get_color().a, SDL_ALPHA_OPAQUE);
968 
969  delete mod;
970 }
971 
972 /// Tests if the BG modification with four arguments is correctly decoded
973 BOOST_AUTO_TEST_CASE(test_bg_modification_decoding_4_args)
974 {
975  environment_setup env_setup;
976 
977  modification_queue queue = modification::decode("~BG(1,2,3,4)");
978 
979  BOOST_REQUIRE_EQUAL(queue.size(), 1);
980 
981  background_modification* mod = dynamic_cast<background_modification*>(queue.top());
982 
983  // The dynamic_cast returns nullptr if the argument doesn't match the type
984  BOOST_REQUIRE(mod != nullptr);
985 
986  BOOST_CHECK_EQUAL(mod->get_color().r, 1);
987  BOOST_CHECK_EQUAL(mod->get_color().g, 2);
988  BOOST_CHECK_EQUAL(mod->get_color().b, 3);
989  BOOST_CHECK_EQUAL(mod->get_color().a, 4);
990 
991  delete mod;
992 }
993 
994 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.
const std::vector< Uint32 > & tc_info(const std::string &name)
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: image.cpp:722
A modified priority queue used to order image modifications.
Overlay with ToD darkening (DARKEN).
The paths manager is responsible for recording the various paths that binary files may be located at...
Definition: filesystem.hpp:210
BOOST_AUTO_TEST_SUITE(test_map_location)
Mask (MASK) modification.
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).
GLsizei const char ** path
Definition: glew.h:4654
GLuint id
Definition: glew.h:1647
Crop (CROP) modification.
void add_color_info(const config &v)
config & add_child(const std::string &key)
Definition: config.cpp:743
Overlay with ToD brightening (BRIGHTEN).
Base abstract class for an image-path modification.
static modification_queue decode(const std::string &)
Decodes modifications from a modification string.
LIGHT (L) modification.
modification * top() const
Returns the top element in the queue .
A color range definition is made of four reference RGB colors, used for calculating conversions from ...
Definition: color_range.hpp:54
size_t i
Definition: function.cpp:1057
Declarations for File-IO.
size_t size() const
Returns the number of elements in the queue.
Opacity (O) modification.
const GLfloat * tc
Definition: glew.h:12749
GLuint const GLchar * name
Definition: glew.h:1782
const color_range & color_info(const std::string &name)
this module manages the cache of images.
Definition: image.cpp:75
Standard logging facilities (interface).
std::map< Uint32, Uint32 > recolor_range(const color_range &new_range, const std::vector< Uint32 > &old_rgb)
Converts a source palette using the specified color_range object.
Definition: color_range.cpp:30
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:83
Helper class to redirect the output of the logger in a certain scope.
Definition: log.hpp:71
GLsizei const GLcharARB ** string
Definition: glew.h:4503
Mirror (FL) modification.
Scaling modifications base class.