1 | #include <iostream>
|
---|
2 | #include <string>
|
---|
3 | #include <math.h>
|
---|
4 |
|
---|
5 | #include "gtest/gtest.h"
|
---|
6 | #include "mbase/MEnv.h"
|
---|
7 | #include "mbase/MLog.h"
|
---|
8 | #include "../mbase/MParContainer.h"
|
---|
9 | #include "mfileio/MMatrix.h"
|
---|
10 |
|
---|
11 | using namespace std;
|
---|
12 |
|
---|
13 | class testMMatrix : public ::testing::Test {
|
---|
14 | protected:
|
---|
15 | // You can remove any or all of the following functions if its body
|
---|
16 | // is empty.
|
---|
17 | const std::string path2test = "./mtest/MMatrixTEST/";
|
---|
18 |
|
---|
19 | testMMatrix() {
|
---|
20 | // You can do set-up work for each test here.
|
---|
21 | }
|
---|
22 |
|
---|
23 | virtual ~testMMatrix() {
|
---|
24 | // You can do clean-up work that doesn't throw exceptions here.
|
---|
25 | }
|
---|
26 |
|
---|
27 | // If the constructor and destructor are not enough for setting up
|
---|
28 | // and cleaning up each test, you can define the following methods:
|
---|
29 |
|
---|
30 | virtual void SetUp() {
|
---|
31 | // Code here will be called immediately after the constructor (right
|
---|
32 | // before each test).
|
---|
33 | }
|
---|
34 |
|
---|
35 | virtual void TearDown() {
|
---|
36 | // Code here will be called immediately after each test (right
|
---|
37 | // before the destructor).
|
---|
38 | }
|
---|
39 |
|
---|
40 | // Objects declared here can be used by all tests in the test case for Foo.
|
---|
41 | };
|
---|
42 | //------------------------------------------------------------------------------
|
---|
43 | TEST_F(testMMatrix, ParseCorrectFile) {
|
---|
44 |
|
---|
45 | // The MMatrix will parse a text file specified in the configuration file
|
---|
46 | // e.g. ceres.rc. The Data can then be used in the simulation.
|
---|
47 | // For example it is used to parse and contain the 1440 temporal offsets of
|
---|
48 | // the telkscope pixels.
|
---|
49 | try{
|
---|
50 |
|
---|
51 | // first we need an Menv to parse in the config file
|
---|
52 | MEnv env(
|
---|
53 | (path2test + "config_where_the_path_to_MyData_is_defined.rc" ).c_str()
|
---|
54 | );
|
---|
55 |
|
---|
56 | // now we create the data container itself. The constructor has two
|
---|
57 | // parameters:
|
---|
58 | // 1) A name
|
---|
59 | // 2) I dont know... its called titel internal in the MParContainer.
|
---|
60 | MMatrix A("Any name related with A","titel");
|
---|
61 |
|
---|
62 | // the MMatrix container is still empty yet. We now call the ReadEnv()
|
---|
63 | // method inherited by MParContainer.
|
---|
64 | // Parameters:
|
---|
65 | // 1) the MEnv class which has parsed in the config file
|
---|
66 | // 2) the keyword used in the configfile for this data container
|
---|
67 | // 3) A verbosity flag which tells you wether the file defined in the config
|
---|
68 | // has been found or not.
|
---|
69 | // the integer return value is ignored here
|
---|
70 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
71 |
|
---|
72 | // The file specified in the config file is supposed to hold a 3 x 3 Matrix
|
---|
73 | // Since the data matrix called 'fM' of the MMatrix is public we can
|
---|
74 | // directly access the data and check.
|
---|
75 | ASSERT_EQ( 3, A.fM.size() );
|
---|
76 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
77 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
78 | ASSERT_EQ( 3, A.fM[2].size() );
|
---|
79 |
|
---|
80 | EXPECT_EQ( 1.1, A.fM[0][0] );
|
---|
81 | EXPECT_EQ( 2, A.fM[0][1] );
|
---|
82 | EXPECT_EQ( 3, A.fM[0][2] );
|
---|
83 | EXPECT_EQ( 4, A.fM[1][0] );
|
---|
84 | EXPECT_EQ( 5.5, A.fM[1][1] );
|
---|
85 | EXPECT_EQ( 6, A.fM[1][2] );
|
---|
86 | EXPECT_EQ( 7, A.fM[2][0] );
|
---|
87 | EXPECT_EQ( 8, A.fM[2][1] );
|
---|
88 | EXPECT_EQ( 9.9, A.fM[2][2] );
|
---|
89 | }
|
---|
90 | catch (std::exception &error){
|
---|
91 | cout << error.what();
|
---|
92 | }
|
---|
93 | }
|
---|
94 | //------------------------------------------------------------------------------
|
---|
95 | TEST_F(testMMatrix, LineBreak_CRLF) {
|
---|
96 |
|
---|
97 | // Check the CRLF linebreak as it is used by several Computers as Mac and
|
---|
98 | // Windows.
|
---|
99 | // For example Dominik and Sebastian exchanged emails with data.csv. Both had
|
---|
100 | // Ubuntu 14 machines. The file was mangeled from LF only, as it is common on
|
---|
101 | // Linux to CRLF !
|
---|
102 | try{
|
---|
103 |
|
---|
104 | // CR and LF i.e. \r\n i.e. 10 and 13
|
---|
105 | MEnv env( (path2test + "LineBreak_CRLF.rc" ).c_str() );
|
---|
106 | MMatrix A("Any name related with A","titel");
|
---|
107 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
108 |
|
---|
109 | ASSERT_EQ( 3, A.fM.size() );
|
---|
110 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
111 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
112 | ASSERT_EQ( 3, A.fM[2].size() );
|
---|
113 |
|
---|
114 | EXPECT_EQ( 1.1, A.fM[0][0] );
|
---|
115 | EXPECT_EQ( 2, A.fM[0][1] );
|
---|
116 | EXPECT_EQ( 3, A.fM[0][2] );
|
---|
117 | EXPECT_EQ( 4, A.fM[1][0] );
|
---|
118 | EXPECT_EQ( 5.5, A.fM[1][1] );
|
---|
119 | EXPECT_EQ( 6, A.fM[1][2] );
|
---|
120 | EXPECT_EQ( 7, A.fM[2][0] );
|
---|
121 | EXPECT_EQ( 8, A.fM[2][1] );
|
---|
122 | EXPECT_EQ( 9.9, A.fM[2][2] );
|
---|
123 | }
|
---|
124 | catch (std::exception &error){
|
---|
125 | cout << error.what();
|
---|
126 | }
|
---|
127 | }
|
---|
128 | //------------------------------------------------------------------------------
|
---|
129 | TEST_F(testMMatrix, LineBreak_CR) {
|
---|
130 |
|
---|
131 | // CR only linebreak is hopefully not common anymore. It was used by Mac.
|
---|
132 | try{
|
---|
133 |
|
---|
134 | // CR and LF i.e. \r\n i.e. 10 and 13
|
---|
135 | MEnv env( (path2test + "LineBreak_CR.rc" ).c_str() );
|
---|
136 | MMatrix A("Any name related with A","titel");
|
---|
137 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
138 |
|
---|
139 | ASSERT_EQ( 3, A.fM.size() );
|
---|
140 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
141 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
142 | ASSERT_EQ( 3, A.fM[2].size() );
|
---|
143 |
|
---|
144 | EXPECT_EQ( 1.1, A.fM[0][0] );
|
---|
145 | EXPECT_EQ( 2, A.fM[0][1] );
|
---|
146 | EXPECT_EQ( 3, A.fM[0][2] );
|
---|
147 | EXPECT_EQ( 4, A.fM[1][0] );
|
---|
148 | EXPECT_EQ( 5.5, A.fM[1][1] );
|
---|
149 | EXPECT_EQ( 6, A.fM[1][2] );
|
---|
150 | EXPECT_EQ( 7, A.fM[2][0] );
|
---|
151 | EXPECT_EQ( 8, A.fM[2][1] );
|
---|
152 | EXPECT_EQ( 9.9, A.fM[2][2] );
|
---|
153 | }
|
---|
154 | catch (std::exception &error){
|
---|
155 | cout << error.what();
|
---|
156 | }
|
---|
157 | }
|
---|
158 | //------------------------------------------------------------------------------
|
---|
159 | TEST_F(testMMatrix, CommentOnly) {
|
---|
160 |
|
---|
161 | // We read in a csv file with only comments line in there. The resulting
|
---|
162 | // Matrix shall be empty.
|
---|
163 | try{
|
---|
164 |
|
---|
165 | MEnv env( (path2test + "comment_only.rc" ).c_str() );
|
---|
166 | MMatrix A("Any name related with A","titel");
|
---|
167 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
168 |
|
---|
169 | ASSERT_EQ( 0, A.fM.size() );
|
---|
170 | }
|
---|
171 | catch (std::exception &error){
|
---|
172 | cout << error.what();
|
---|
173 | }
|
---|
174 | }
|
---|
175 | //------------------------------------------------------------------------------
|
---|
176 | TEST_F(testMMatrix, DataOnly) {
|
---|
177 |
|
---|
178 | // The file has no comments at all. 3x3 Matrix data only
|
---|
179 | try{
|
---|
180 |
|
---|
181 | MEnv env( (path2test + "data_only.rc" ).c_str() );
|
---|
182 | MMatrix A("Any name related with A","titel");
|
---|
183 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
184 |
|
---|
185 | ASSERT_EQ( 3, A.fM.size() );
|
---|
186 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
187 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
188 | ASSERT_EQ( 3, A.fM[2].size() );
|
---|
189 |
|
---|
190 | EXPECT_EQ( 1.1, A.fM[0][0] );
|
---|
191 | EXPECT_EQ( 2, A.fM[0][1] );
|
---|
192 | EXPECT_EQ( 3, A.fM[0][2] );
|
---|
193 | EXPECT_EQ( 4, A.fM[1][0] );
|
---|
194 | EXPECT_EQ( 5.5, A.fM[1][1] );
|
---|
195 | EXPECT_EQ( 6, A.fM[1][2] );
|
---|
196 | EXPECT_EQ( 7, A.fM[2][0] );
|
---|
197 | EXPECT_EQ( 8, A.fM[2][1] );
|
---|
198 | EXPECT_EQ( 9.9, A.fM[2][2] );
|
---|
199 | }
|
---|
200 | catch (std::exception &error){
|
---|
201 | cout << error.what();
|
---|
202 | }
|
---|
203 | }
|
---|
204 | //------------------------------------------------------------------------------
|
---|
205 | TEST_F(testMMatrix, data_and_comments_mixed) {
|
---|
206 |
|
---|
207 | try{
|
---|
208 |
|
---|
209 | MEnv env( (path2test + "data_and_comments_mixed.rc" ).c_str() );
|
---|
210 | MMatrix A("Any name related with A","titel");
|
---|
211 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
212 |
|
---|
213 | ASSERT_EQ( 3, A.fM.size() );
|
---|
214 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
215 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
216 | ASSERT_EQ( 3, A.fM[2].size() );
|
---|
217 |
|
---|
218 | EXPECT_EQ( 1.1, A.fM[0][0] );
|
---|
219 | EXPECT_EQ( 2, A.fM[0][1] );
|
---|
220 | EXPECT_EQ( 3, A.fM[0][2] );
|
---|
221 | EXPECT_EQ( 4, A.fM[1][0] );
|
---|
222 | EXPECT_EQ( 5.5, A.fM[1][1] );
|
---|
223 | EXPECT_EQ( 6, A.fM[1][2] );
|
---|
224 | EXPECT_EQ( 7, A.fM[2][0] );
|
---|
225 | EXPECT_EQ( 8, A.fM[2][1] );
|
---|
226 | EXPECT_EQ( 9.9, A.fM[2][2] );
|
---|
227 | }
|
---|
228 | catch (std::exception &error){
|
---|
229 | cout << error.what();
|
---|
230 | }
|
---|
231 | }
|
---|
232 | //------------------------------------------------------------------------------
|
---|
233 | TEST_F(testMMatrix, missing_delimiter) {
|
---|
234 | // when a delimiter is missing, a fatal exception must be thrown
|
---|
235 | bool error_detected = false;
|
---|
236 | try{
|
---|
237 |
|
---|
238 | MEnv env( (path2test + "missing_delimiter.rc" ).c_str() );
|
---|
239 | MMatrix A("Any name related with A","titel");
|
---|
240 |
|
---|
241 | // right here an exception shall be thrown because of the missing delimiter
|
---|
242 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
243 |
|
---|
244 | }
|
---|
245 | catch (std::exception error){
|
---|
246 | error_detected = true;
|
---|
247 | }
|
---|
248 | EXPECT_TRUE(error_detected);
|
---|
249 | }
|
---|
250 | //------------------------------------------------------------------------------
|
---|
251 | TEST_F(testMMatrix, bad_floating_point_number) {
|
---|
252 | // when a floating point number is bad, a fatal exception must be thrown
|
---|
253 | bool error_detected = false;
|
---|
254 | try{
|
---|
255 |
|
---|
256 | MEnv env( (path2test + "bad_floating_point_number.rc" ).c_str() );
|
---|
257 | MMatrix A("Any name related with A","titel");
|
---|
258 |
|
---|
259 | // expect exception because of bad floating point number
|
---|
260 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
261 |
|
---|
262 | }
|
---|
263 | catch (std::exception error){
|
---|
264 | error_detected = true;
|
---|
265 | }
|
---|
266 | EXPECT_TRUE(error_detected);
|
---|
267 | }
|
---|
268 | //------------------------------------------------------------------------------
|
---|
269 | TEST_F(testMMatrix, NaN_Inf_exponent) {
|
---|
270 |
|
---|
271 | // +Inf, -Inf, Inf
|
---|
272 | // NaN, 1e3, 42e13.37
|
---|
273 | try{
|
---|
274 |
|
---|
275 | MEnv env( (path2test + "NaN_Inf_exponent.rc" ).c_str() );
|
---|
276 | MMatrix A("Any name related with A","titel");
|
---|
277 |
|
---|
278 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
279 |
|
---|
280 | // check dimension
|
---|
281 | ASSERT_EQ( 2, A.fM.size() );
|
---|
282 | ASSERT_EQ( 3, A.fM[0].size() );
|
---|
283 | ASSERT_EQ( 3, A.fM[1].size() );
|
---|
284 |
|
---|
285 | // +Inf
|
---|
286 | EXPECT_FALSE( std::signbit( A.fM[0][0]) );
|
---|
287 | EXPECT_TRUE( std::isinf( A.fM[0][0]) );
|
---|
288 | // -Inf
|
---|
289 | EXPECT_TRUE( std::signbit( A.fM[0][1]) );
|
---|
290 | EXPECT_TRUE( std::isinf( A.fM[0][1]) );
|
---|
291 | // Inf
|
---|
292 | EXPECT_FALSE( std::signbit( A.fM[0][2]) );
|
---|
293 | EXPECT_TRUE( std::isinf( A.fM[0][2]) );
|
---|
294 |
|
---|
295 | EXPECT_TRUE( std::isnan( A.fM[1][0]) );
|
---|
296 | EXPECT_EQ( 1e3, A.fM[1][1] );
|
---|
297 | EXPECT_EQ( 13.37e42, A.fM[1][2] );
|
---|
298 | }
|
---|
299 | catch (std::exception &error){
|
---|
300 | cout << error.what();
|
---|
301 | }
|
---|
302 | }
|
---|
303 | //------------------------------------------------------------------------------
|
---|
304 | TEST_F(testMMatrix, whitespaces_and_tabs) {
|
---|
305 | // whitespaces are allowd and must not effect the parsing
|
---|
306 | try{
|
---|
307 |
|
---|
308 | MEnv env( (path2test + "whitespaces_and_tabs.rc" ).c_str() );
|
---|
309 | MMatrix A("Any name related with A","titel");
|
---|
310 |
|
---|
311 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
312 |
|
---|
313 | // check dimension
|
---|
314 | // we expect 9 row and 3 columns each with 1,2,3 in there
|
---|
315 |
|
---|
316 | ASSERT_EQ( 9, A.fM.size() );
|
---|
317 | for(int row=0; row<9; row++){
|
---|
318 |
|
---|
319 | ASSERT_EQ( 3, A.fM[row].size() );
|
---|
320 | for(int col=0; col<3; col++){
|
---|
321 |
|
---|
322 | EXPECT_EQ( (col+1) , A.fM[row][col] );
|
---|
323 | }
|
---|
324 | }
|
---|
325 | }
|
---|
326 | catch (std::exception &error){
|
---|
327 | cout << error.what();
|
---|
328 | }
|
---|
329 | }
|
---|
330 | //------------------------------------------------------------------------------
|
---|
331 | TEST_F(testMMatrix, csv_file_does_not_exist) {
|
---|
332 | // There must be a fatal exception when the csv file does not exist
|
---|
333 | bool error_detected = false;
|
---|
334 | try{
|
---|
335 |
|
---|
336 | MEnv env( (path2test + "csv_file_does_not_exist.rc" ).c_str() );
|
---|
337 | MMatrix A("Any name related with A","titel");
|
---|
338 |
|
---|
339 | A.ReadEnv(env,"MyData",kFALSE);
|
---|
340 | }
|
---|
341 | catch (std::exception &error){
|
---|
342 | error_detected = true;
|
---|
343 | }
|
---|
344 | EXPECT_TRUE(error_detected);
|
---|
345 | }
|
---|
346 | //------------------------------------------------------------------------------
|
---|
347 | TEST_F(testMMatrix, key_does_not_exist_in_config_file) {
|
---|
348 | // There must be a fatal exception when the key can not be found in the
|
---|
349 | // config file.
|
---|
350 | bool error_detected = false;
|
---|
351 | try{
|
---|
352 |
|
---|
353 | MEnv env( (path2test + "key_does_not_exist_in_config_file.rc" ).c_str() );
|
---|
354 | MMatrix A("Any name related with A","titel");
|
---|
355 |
|
---|
356 | A.ReadEnv(env,"KeyToDataThatDoesNotExistInTheConfigFile",kFALSE);
|
---|
357 | }
|
---|
358 | catch (std::exception &error){
|
---|
359 | error_detected = true;
|
---|
360 | }
|
---|
361 | EXPECT_TRUE(error_detected);
|
---|
362 | }
|
---|
363 | //------------------------------------------------------------------------------ |
---|