1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 */
7
8 #include "orcus_test_global.hpp"
9 #include "orcus/spreadsheet/document.hpp"
10 #include "orcus/spreadsheet/sheet.hpp"
11 #include "orcus/pstring.hpp"
12 #include "orcus/stream.hpp"
13
14 #include <sstream>
15 #include <cmath>
16 #include <iostream>
17 #include <chrono>
18
19 namespace orcus { namespace test {
20
stack_printer(const char * msg)21 stack_printer::stack_printer(const char* msg) :
22 m_msg(msg)
23 {
24 std::cerr << m_msg << ": --begin" << std::endl;
25 m_start_time = get_time();
26 }
27
~stack_printer()28 stack_printer::~stack_printer()
29 {
30 double end_time = get_time();
31 std::cerr << m_msg << ": --end (duration: " << (end_time-m_start_time) << " sec)" << std::endl;
32 }
33
get_time() const34 double stack_printer::get_time() const
35 {
36 double v = std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
37 return v / 1000.0;
38 }
39
assert_error(const char * filename,size_t line_no,const char * msg)40 assert_error::assert_error(const char* filename, size_t line_no, const char* msg)
41 {
42 std::ostringstream os;
43 os << filename << ":" << line_no << ": " << msg;
44 m_msg = os.str();
45 }
46
what() const47 const char* assert_error::what() const noexcept
48 {
49 return m_msg.data();
50 }
51
get_content_check(const spreadsheet::document & doc)52 std::string get_content_check(const spreadsheet::document& doc)
53 {
54 std::ostringstream os;
55 doc.dump_check(os);
56 return os.str();
57 }
58
get_content_as_csv(const spreadsheet::document & doc,spreadsheet::sheet_t sheet_index)59 std::string get_content_as_csv(const spreadsheet::document& doc, spreadsheet::sheet_t sheet_index)
60 {
61 const spreadsheet::sheet* sh = doc.get_sheet(sheet_index);
62 if (!sh)
63 return std::string();
64
65 std::ostringstream os;
66 sh->dump_csv(os);
67 return os.str();
68 }
69
verify_content(const char * filename,size_t line_no,const pstring & expected,const std::string & actual)70 void verify_content(
71 const char* filename, size_t line_no, const pstring& expected, const std::string& actual)
72 {
73 pstring s1 = expected;
74 pstring s2(actual.data(), actual.size());
75 s1 = s1.trim();
76 s2 = s2.trim();
77
78 if (s1 != s2)
79 {
80 // TODO : improve the error message to make it more viewer-friendly.
81
82 size_t diff_pos = locate_first_different_char(s1, s2);
83 std::string msg_s1 = create_parse_error_output(s1, diff_pos);
84 std::string msg_s2 = create_parse_error_output(s2, diff_pos);
85
86 std::ostringstream os;
87 os << "content is not as expected: " << std::endl << std::endl
88 << "* expected:" << std::endl << std::endl
89 << msg_s1 << std::endl
90 << "* actual:" << std::endl << std::endl
91 << msg_s2;
92
93 throw assert_error(filename, line_no, os.str().data());
94 }
95 }
96
verify_content(const char * filename,size_t line_no,const spreadsheet::document & doc,const pstring & expected)97 void verify_content(
98 const char* filename, size_t line_no, const spreadsheet::document& doc, const pstring& expected)
99 {
100 std::string actual = get_content_check(doc);
101 verify_content(filename, line_no, expected, actual);
102 }
103
verify_value_to_decimals(const char * filename,size_t line_no,double expected,double actual,int decimals)104 void verify_value_to_decimals(
105 const char* filename, size_t line_no, double expected, double actual, int decimals)
106 {
107 for (int i = 0; i < decimals; ++i)
108 {
109 expected *= 10.0;
110 actual *= 10.0;
111 }
112
113 long expected_i = std::lround(expected);
114 long actual_i = std::lround(actual);
115
116 if (expected_i == actual_i)
117 return;
118
119 expected = expected_i;
120 actual = actual_i;
121
122 for (int i = 0; i < decimals; ++i)
123 {
124 expected /= 10.0;
125 actual /= 10.0;
126 }
127
128 std::ostringstream os;
129 os << "value is not as expected: (expected: " << expected << "; actual: " << actual << ")";
130 throw assert_error(filename, line_no, os.str().data());
131 }
132
prefix_multiline_string(const pstring & str,const pstring & prefix)133 std::string prefix_multiline_string(const pstring& str, const pstring& prefix)
134 {
135 std::ostringstream os;
136
137 const char* p = str.data();
138 const char* p_end = p + str.size();
139
140 const char* p0 = nullptr;
141 for (; p != p_end; ++p)
142 {
143 if (!p0)
144 p0 = p;
145
146 if (*p == '\n')
147 {
148 os << prefix << pstring(p0, std::distance(p0, p)) << '\n';
149 p0 = nullptr;
150 }
151 }
152
153 if (p0)
154 os << prefix << pstring(p0, std::distance(p0, p));
155
156 return os.str();
157 }
158
159 }}
160
161 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
162