bl_test_context_baseapp.h (3655B)
1 // This file is part of Blend2D project <https://blend2d.com> 2 // 3 // See blend2d.h or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 // This file provides utility classes and functions shared between some tests. 7 8 #ifndef BLEND2D_TEST_CONTEXT_BASEAPP_H_INCLUDED 9 #define BLEND2D_TEST_CONTEXT_BASEAPP_H_INCLUDED 10 11 #include <blend2d.h> 12 #include <vector> 13 14 #include "bl_test_context_utilities.h" 15 #include "../commons/cmdline.h" 16 17 namespace ContextTests { 18 19 class BaseTestApp { 20 public: 21 struct TestInfo { 22 BLString name; 23 BLString id; 24 }; 25 26 //! Default options. 27 TestOptions default_options {}; 28 //! Current options (inherited from default options and parsed from command line). 29 TestOptions options {}; 30 //! Tests cases to execute. 31 TestCases test_cases; 32 33 //! Font data to use during text rendering tests. 34 BLFontData font_data; 35 36 // Statistics from run_multiple(). 37 uint32_t mismatch_count {}; 38 39 template<typename T> 40 struct CaseIterator { 41 const std::vector<T>& options; 42 uint32_t index {}; 43 uint32_t count {}; 44 bool randomized {}; 45 T random_case {}; 46 47 inline CaseIterator(const std::vector<T>& options, bool randomized, T random_case = T::kRandom) 48 : options(options), 49 index(0), 50 count(randomized ? uint32_t(1) : uint32_t(options.size())), 51 randomized(randomized), 52 random_case(random_case) {} 53 54 inline bool valid() const { return index < count; } 55 inline T value() const { return randomized ? random_case : options[index]; } 56 57 inline bool next() { return ++index < count; } 58 }; 59 60 BaseTestApp(); 61 ~BaseTestApp(); 62 63 static TestOptions make_default_options(); 64 bool parse_common_options(const CmdLine& cmd_line); 65 66 template<typename RunFunc> 67 void dispatch_runs(RunFunc&& run) { 68 for (CommandId command_id : test_cases.command_ids) { 69 CaseIterator<StyleId> style_id_iterator(test_cases.style_ids, is_random_style(options.style_id), options.style_id); 70 do { 71 CaseIterator<StyleOp> style_op_iterator(test_cases.style_ops, options.style_op == StyleOp::kRandom); 72 do { 73 CaseIterator<CompOp> comp_op_iterator(test_cases.comp_ops, options.comp_op == CompOp::kRandom); 74 do { 75 CaseIterator<OpacityOp> opacity_op_iterator(test_cases.opacity_ops, options.opacity_op == OpacityOp::kRandom); 76 do { 77 run(command_id, 78 style_id_iterator.value(), 79 style_op_iterator.value(), 80 comp_op_iterator.value(), 81 opacity_op_iterator.value()); 82 } while (opacity_op_iterator.next()); 83 } while (comp_op_iterator.next()); 84 } while (style_op_iterator.next()); 85 } while (style_id_iterator.next()); 86 } 87 } 88 89 void print_app_info(const char* title, bool quiet) const; 90 void print_common_options(const TestOptions& test_options) const; 91 void print_formats() const; 92 void print_comp_ops() const; 93 void print_opacity_ops() const; 94 void print_style_ids() const; 95 void print_style_ops() const; 96 void print_commands() const; 97 98 bool run_multiple(CommandId command_id, const TestInfo& info, ContextTester& a_tester, ContextTester& b_tester, uint32_t max_diff); 99 void find_problem(CommandId command_id, const TestInfo& info, ContextTester& a_tester, ContextTester& b_tester, uint32_t max_diff); 100 101 bool check_output(const char* test_id, const ContextTester& a_tester, const ContextTester& b_tester, uint32_t max_diff); 102 void store_image(const BLImage& image, const char* name, const char* suffix = nullptr) const; 103 }; 104 105 } // {ContextTests} 106 107 #endif // BLEND2D_TEST_CONTEXT_BASEAPP_H_INCLUDED