Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
compareTool.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49
50 #include <QString>
51 #include <QStringList>
52 #include <QSettings>
53 #include <QFileInfo>
54 #include <QTextStream>
55
56 #include <cmath>
57 #include <limits>
58 #include <iostream>
59
60
61 /* Test File specification:
62 Doubles can be given as:
63
64 Exact test:
65 VALUE_DOUBLE=1.0
66
67 Tolerance test (0.0001)
68 VALUE_DOUBLE=1.0,0.0001
69
70
71 */
72
73
74 bool compareDouble(QString _key , QVariant _result, QVariant _reference) {
75
76 // maximal allowed double tolerance
77 double tolerance = std::numeric_limits<double>::epsilon();
78
79 // Check if the reference consists of two colon separated values
80 // Second value would specify maximal allowed tolerance
81 QStringList referenceData = _reference.toString().split(':');
82 if ( referenceData.size() == 2) {
83 tolerance = referenceData[1].toDouble();
84 }
85
86
87 double result = _result.toDouble();
88 double reference = referenceData[0].toDouble();
89
90 if ( fabs(result-reference) <= tolerance ) {
91 return true;
92 } else {
93
94 //qcerr.setRealNumberPrecision(40);
95 std::cerr.precision(40);
96 std::cerr << "===================================================================\n";
97 std::cerr << "Comparison failed for key " << _key.toStdString() << " :\n";
98 std::cerr << "Result: " << result << "\n";
99 std::cerr << "Expected: " << reference << "\n";
100 std::cerr << "Difference: " << fabs(result-reference) << "\n";
101 std::cerr << "Allowed tolerance was: " << tolerance << "\n";
102 std::cerr << "===================================================================\n";
103 return false;
104 }
105
106 }
107
108 bool compareString(QString _key ,QVariant _result, QVariant _reference) {
109
110 QString resultStr = _result.toString().simplified();
111 QString resultRef = _reference.toString().simplified();
112
113 if (resultStr == resultRef ) {
114 return true;
115 } else {
116 std::cerr << "Comparison failed for key " << _key.toStdString() << " :\n";
117 std::cerr << "Result: " << resultStr.toStdString() << " ; Expected: " << resultRef.toStdString() << "\n";
118 return false;
119 }
120
121 }
122
123 int main(int argv, char **args)
124 {
125 std::cout << "============================================================\n" ;
126 std::cout << "Executing compare tool\n";
127 std::cout << "Comparing results to reference:\n" ;
128
129 // Flag if everything went fine
130 bool ok = true;
131
132 // Return if we did not get exactly two arguments
133 if ( argv != 3 ) {
134 std::cerr << "Wrong number of arguments!\n";
135 std::cerr << "Usage:\n";
136 std::cerr << "compareTool ResultFile ReferenceFile\n";
137 return(1);
138 }
139
140 QString file1(args[1]);
141 QString file2(args[2]);
142
143 QFileInfo resultFileInfo(file1);
144 if ( !resultFileInfo.exists() ) {
145 std::cerr << "ERROR! Result file: " << file1.toStdString() << " does not exist!\n";
146
147 return 1;
148 }
149
150 QFileInfo referenceFileInfo(file2);
151 if ( !referenceFileInfo.exists() ) {
152 std::cerr << "ERROR! Reference file: " << file2.toStdString() << " does not exist!\n";
153 return 1;
154 }
155
156 QSettings resultFile(file1,QSettings::IniFormat);
157 QSettings referenceFile(file2,QSettings::IniFormat);
158
159 if ( resultFile.status() != QSettings::NoError) {
160 std::cerr << "QSettings error when opening result file: " << file1.toStdString() << "\n";
161 return 1;
162 }
163
164 if ( referenceFile.status() != QSettings::NoError) {
165 std::cerr << "QSettings error when opening result reference file: " << file2.toStdString() << "\n";
166 return 1;
167 }
168
169 QStringList toplevelKeys = referenceFile.childKeys();
170 QStringList groups = referenceFile.childGroups();
171
172 if ( groups.size() == 0 ) {
173 for ( int i = 0 ; i < toplevelKeys.size(); ++i) {
174 if ( resultFile.contains(toplevelKeys[i]) ) {
175 if ( toplevelKeys[i].endsWith("_DOUBLE") ) {
176 ok &= compareDouble(toplevelKeys[i],resultFile.value(toplevelKeys[i]), referenceFile.value(toplevelKeys[i]));
177 } else
178 ok &= compareString( toplevelKeys[i],resultFile.value(toplevelKeys[i]), referenceFile.value(toplevelKeys[i]));
179 } else {
180 std::cerr << "Missing key in result file: " << toplevelKeys[i].toStdString() << "\n";
181 ok = false;
182 }
183
184 }
185
186
187 } else {
188 std::cerr << "Multiple levels!" << "\n";
189 return 1;
190 }
191
192
193 if ( ! ok ) {
194 std::cerr << "At least one of the tests failed!\n";
195 return 1;
196 }
197
198 return(0);
199 }