1 // This file is part of the SpeedCrunch project
2 // Copyright (C) 2004-2006 Ariya Hidayat <ariya@kde.org>
3 // Copyright (C) 2007-2009, 2013, 2016 @heldercorreia
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; see the file COPYING. If not, write to
17 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 // Boston, MA 02110-1301, USA.
19
20 #include "core/evaluator.h"
21 #include "core/settings.h"
22 #include "core/numberformatter.h"
23 #include "tests/testcommon.h"
24
25 #include <QtCore/QCoreApplication>
26
27 #include <string>
28 #include <iostream>
29
30 using namespace std;
31
32 typedef Quantity::Format Format;
33
34 static Evaluator* eval = 0;
35 static int eval_total_tests = 0;
36 static int eval_failed_tests = 0;
37 static int eval_new_failed_tests = 0;
38
39 #define CHECK_AUTOFIX(s,p) checkAutoFix(__FILE__,__LINE__,#s,s,p)
40 #define CHECK_DIV_BY_ZERO(s) checkDivisionByZero(__FILE__,__LINE__,#s,s)
41 #define CHECK_EVAL(x,y) checkEval(__FILE__,__LINE__,#x,x,y)
42 #define CHECK_EVAL_FORMAT(x,y) checkEval(__FILE__,__LINE__,#x,x,y,0,false,true)
43 #define CHECK_EVAL_KNOWN_ISSUE(x,y,n) checkEval(__FILE__,__LINE__,#x,x,y,n)
44 #define CHECK_EVAL_PRECISE(x,y) checkEvalPrecise(__FILE__,__LINE__,#x,x,y)
45 #define CHECK_EVAL_FAIL(x) checkEval(__FILE__,__LINE__,#x,x,"",0,true)
46 #define CHECK_EVAL_FORMAT_FAIL(x) checkEval(__FILE__,__LINE__,#x,x,"",0,true,true)
47 #define CHECK_USERFUNC_SET(x) checkEval(__FILE__,__LINE__,#x,x,"NaN")
48 #define CHECK_USERFUNC_SET_FAIL(x) checkEval(__FILE__,__LINE__,#x,x,"",0,true)
49
checkAutoFix(const char * file,int line,const char * msg,const char * expr,const char * fixed)50 static void checkAutoFix(const char* file, int line, const char* msg, const char* expr, const char* fixed)
51 {
52 ++eval_total_tests;
53
54 string r = eval->autoFix(QString(expr)).toStdString();
55 DisplayErrorOnMismatch(file, line, msg, r, fixed, eval_failed_tests, eval_new_failed_tests);
56 }
57
checkDivisionByZero(const char * file,int line,const char * msg,const QString & expr)58 static void checkDivisionByZero(const char* file, int line, const char* msg, const QString& expr)
59 {
60 ++eval_total_tests;
61
62 eval->setExpression(expr);
63 Quantity rn = eval->evalUpdateAns();
64
65 if (eval->error().isEmpty()) {
66 ++eval_failed_tests;
67 cerr << file << "[" << line << "]\t" << msg << endl
68 << "\tError: " << "division by zero not caught" << endl;
69 }
70 }
71
checkEval(const char * file,int line,const char * msg,const QString & expr,const char * expected,int issue=0,bool shouldFail=false,bool format=false)72 static void checkEval(const char* file, int line, const char* msg, const QString& expr,
73 const char* expected, int issue = 0, bool shouldFail = false, bool format = false)
74 {
75 ++eval_total_tests;
76
77 eval->setExpression(expr);
78 Quantity rn = eval->evalUpdateAns();
79
80 if (!eval->error().isEmpty()) {
81 if (!shouldFail) {
82 ++eval_failed_tests;
83 cerr << file << "[" << line << "]\t" << msg;
84 if (issue)
85 cerr << "\t[ISSUE " << issue << "]";
86 else {
87 cerr << "\t[NEW]";
88 ++eval_new_failed_tests;
89 }
90 cerr << endl;
91 cerr << "\tError: " << qPrintable(eval->error()) << endl;
92 }
93 } else {
94 QString result = (format ? NumberFormatter::format(rn) : DMath::format(rn, Format::Fixed()));
95 result.replace(QString::fromUtf8("−"), "-");
96 if (shouldFail || result != expected) {
97 ++eval_failed_tests;
98 cerr << file << "[" << line << "]\t" << msg;
99 if (issue)
100 cerr << "\t[ISSUE " << issue << "]";
101 else {
102 cerr << "\t[NEW]";
103 ++eval_new_failed_tests;
104 }
105 cerr << endl;
106 cerr << "\tResult : " << result.toLatin1().constData() << endl
107 << "\tExpected : " << (shouldFail ? "should fail" : expected) << endl;
108 }
109 }
110 }
111
checkEvalPrecise(const char * file,int line,const char * msg,const QString & expr,const char * expected)112 static void checkEvalPrecise(const char* file, int line, const char* msg, const QString& expr, const char* expected)
113 {
114 ++eval_total_tests;
115
116 eval->setExpression(expr);
117 Quantity rn = eval->evalUpdateAns();
118
119 // We compare up to 50 decimals, not exact number because it's often difficult
120 // to represent the result as an irrational number, e.g. PI.
121 string result = DMath::format(rn, Format::Fixed() + Format::Precision(50)).toStdString();
122 DisplayErrorOnMismatch(file, line, msg, result, expected, eval_failed_tests, eval_new_failed_tests, 0);
123 }
124
test_constants()125 void test_constants()
126 {
127 CHECK_EVAL("1", "1");
128 }
129
test_exponentiation()130 void test_exponentiation()
131 {
132 CHECK_EVAL("2e10", "20000000000");
133 CHECK_EVAL("2E10", "20000000000");
134 CHECK_EVAL("2e-10", "0.0000000002");
135 CHECK_EVAL("2E0xa", "20000000000");
136 CHECK_EVAL("2e-0xa", "0.0000000002");
137 CHECK_EVAL("0b10b10", "8");
138 CHECK_EVAL("0b10B10", "8");
139 CHECK_EVAL("0b10b-10", "0.5");
140 CHECK_EVAL("0b10b0d2", "8");
141 CHECK_EVAL("0b10b-0d2", "0.5");
142 CHECK_EVAL("0o2o10", "33554432");
143 CHECK_EVAL("0o2O10", "33554432");
144 CHECK_EVAL("0o2C10", "33554432");
145 CHECK_EVAL("0o2o-10", "0.00000011920928955078");
146 CHECK_EVAL("0o2o0d8", "33554432");
147 CHECK_EVAL("0o2o-0d8", "0.00000011920928955078");
148 CHECK_EVAL("0x2h10", "36893488147419103232");
149 CHECK_EVAL("0x2H10", "36893488147419103232");
150 CHECK_EVAL("0x2h-10", "0.00000000000000000011");
151 CHECK_EVAL("0x2h0d16", "36893488147419103232");
152 CHECK_EVAL("0x2h-0d16", "0.00000000000000000011");
153 CHECK_EVAL_FAIL("0x2o11");
154 CHECK_EVAL_FAIL("0b2C11");
155 CHECK_EVAL_FAIL("0o2b11");
156 }
157
test_unary()158 void test_unary()
159 {
160 CHECK_EVAL("-0", "0");
161 CHECK_EVAL("-1", "-1");
162 CHECK_EVAL("--1", "1");
163 CHECK_EVAL("---1", "-1");
164 CHECK_EVAL("----1", "1");
165 CHECK_EVAL("-----1", "-1");
166 CHECK_EVAL("------1", "1");
167
168 CHECK_EVAL("-ABS(1)", "-1");
169 CHECK_EVAL("-ABS(-2)", "-2");
170 CHECK_EVAL("--ABS(-3)", "3");
171 CHECK_EVAL("---ABS(-4)", "-4");
172
173 // Operator ^ has higher precedence than unary minus.
174 CHECK_EVAL("-1^0", "-1");
175 CHECK_EVAL("-1^1", "-1");
176 CHECK_EVAL("-1^2", "-1");
177 CHECK_EVAL("-1^3", "-1");
178
179 CHECK_EVAL("-2^0", "-1");
180 CHECK_EVAL("-2^1", "-2");
181 CHECK_EVAL("-2^2", "-4");
182 CHECK_EVAL("-2^3", "-8");
183 CHECK_EVAL("-2^4", "-16");
184 CHECK_EVAL("-2^5", "-32");
185 CHECK_EVAL("-2^6", "-64");
186 CHECK_EVAL("-2^7", "-128");
187 CHECK_EVAL("-2^8", "-256");
188 CHECK_EVAL("-2^9", "-512");
189 CHECK_EVAL("-2^10", "-1024");
190
191 CHECK_EVAL("(5-7)^2", "4");
192 CHECK_EVAL("-(5-7)^2", "-4");
193
194 CHECK_EVAL("-cos(pi)^3", "1");
195 CHECK_EVAL("1*(-cos(pi)^2)", "-1");
196
197 CHECK_EVAL("3^3^3", "7625597484987");
198
199 CHECK_EVAL("1/-1^2", "-1");
200 CHECK_EVAL("1*-1^2", "-1");
201
202 // Factorial has higher precedence than unary minus.
203 CHECK_EVAL("-1!", "-1");
204 CHECK_EVAL("-2!", "-2");
205 CHECK_EVAL("-3!", "-6");
206
207 // Unicode minus sign
208 CHECK_EVAL("−1", "-1");
209 CHECK_EVAL("−(2*3)", "-6");
210 CHECK_EVAL("2*−1", "-2");
211 CHECK_EVAL("2e−1", "0.2");
212 }
213
test_binary()214 void test_binary()
215 {
216 // See http://en.wikipedia.org/wiki/Empty_product.
217 CHECK_EVAL("0^0", "NaN");
218
219 CHECK_EVAL("1^0", "1");
220 CHECK_EVAL("1^1", "1");
221 CHECK_EVAL("1^2", "1");
222 CHECK_EVAL("1^3", "1");
223
224 CHECK_EVAL("2^0", "1");
225 CHECK_EVAL("2^1", "2");
226 CHECK_EVAL("2^2", "4");
227 CHECK_EVAL("2^3", "8");
228 CHECK_EVAL("2^4", "16");
229 CHECK_EVAL("2^5", "32");
230 CHECK_EVAL("2^6", "64");
231 CHECK_EVAL("2^7", "128");
232 CHECK_EVAL("2^8", "256");
233 CHECK_EVAL("2^9", "512");
234 CHECK_EVAL("2^10", "1024");
235
236 CHECK_EVAL("0+0", "0");
237 CHECK_EVAL("1+0", "1");
238 CHECK_EVAL("0+1", "1");
239 CHECK_EVAL("1+1", "2");
240
241 CHECK_EVAL("0-0", "0");
242 CHECK_EVAL("1-0", "1");
243 CHECK_EVAL("0-1", "-1");
244 CHECK_EVAL("1-1", "0");
245
246 CHECK_EVAL("0−0", "0");
247 CHECK_EVAL("1−0", "1");
248 CHECK_EVAL("0−1", "-1");
249 CHECK_EVAL("1−1", "0");
250
251 CHECK_EVAL("2*3", "6");
252 CHECK_EVAL("2×3", "6");
253 CHECK_EVAL("2⋅3", "6"); // U+22C5 Dot operator.
254 CHECK_EVAL("3*2", "6");
255 CHECK_EVAL("3×2", "6");
256 CHECK_EVAL("3⋅2", "6");
257
258 CHECK_EVAL("10/2", "5");
259 CHECK_EVAL("10÷2", "5");
260 CHECK_EVAL("2/10", "0.2");
261 CHECK_EVAL("2÷10", "0.2");
262
263 // Check that parentheses are added in unit conversion results when needed
264 CHECK_EVAL("1 meter -> 10 meter", "0.1 (10 meter)");
265 CHECK_EVAL("1 meter -> .1 meter", "10 (.1 meter)");
266 CHECK_EVAL("1 meter -> -1 meter", "-1 (-1 meter)");
267 CHECK_EVAL("1 meter -> 0xa meter", "0.1 (0xa meter)");
268 CHECK_EVAL("1 meter second -> 10 meter second", "0.1 (10 meter second)");
269 CHECK_EVAL("1 meter second -> meter 10 second", "0.1 meter 10 second");
270 CHECK_EVAL("1 meter second -> meter second 10", "0.1 (meter second 10)");
271 CHECK_EVAL("1 meter -> meter + meter", "0.5 (meter + meter)");
272 CHECK_EVAL("1 meter -> meter - 2meter", "-1 (meter - 2meter)");
273 CHECK_EVAL("1 meter -> meter", "1 meter");
274 CHECK_EVAL("1 (10 meter) -> meter", "10 meter");
275 }
276
test_divide_by_zero()277 void test_divide_by_zero()
278 {
279 CHECK_DIV_BY_ZERO("1/0");
280 CHECK_DIV_BY_ZERO("1 / sin 0");
281 CHECK_DIV_BY_ZERO("1/sin(pi)");
282 CHECK_DIV_BY_ZERO("1/sin (pi");
283 CHECK_DIV_BY_ZERO("1/sin pi");
284 CHECK_DIV_BY_ZERO("1 / cos (pi/2)");
285 CHECK_DIV_BY_ZERO("1 / cos(pi/2");
286 CHECK_DIV_BY_ZERO("1/cos(pi/2)");
287 CHECK_DIV_BY_ZERO("1/tan(0)");
288 CHECK_DIV_BY_ZERO("1/tan 0");
289 CHECK_DIV_BY_ZERO("-1/trunc(0.123)");
290 CHECK_DIV_BY_ZERO("1/round(0.456)");
291 CHECK_DIV_BY_ZERO("-1/binompmf(1;10;0)");
292 CHECK_DIV_BY_ZERO("-345.3 / binompmf (1; 10; 0)");
293 }
294
test_radix_char()295 void test_radix_char()
296 {
297 // Backup current settings
298 Settings* settings = Settings::instance();
299 char radixCharacter = settings->radixCharacter();
300
301 settings->setRadixCharacter('*');
302
303 CHECK_EVAL("1+.5", "1.5");
304 CHECK_EVAL("1+,5", "1.5");
305 CHECK_EVAL(".5*,5", "0.25");
306 CHECK_EVAL("1.01+2,02", "3.03");
307
308 CHECK_EVAL("0b1.0 + 1", "2");
309 CHECK_EVAL("0b1.1 * 1", "1.5");
310 CHECK_EVAL("0b01.010 / 1", "1.25");
311 CHECK_EVAL("-0b.010 - 1", "-1.25");
312
313 CHECK_EVAL("0o.7 + 1", "1.875");
314 CHECK_EVAL("-0o.7 + 1", "0.125");
315
316 CHECK_EVAL("0x.f + 1", "1.9375");
317 CHECK_EVAL("-0x.f + 1", "0.0625");
318
319 CHECK_EVAL("1/.1", "10"); // ISSUE 151
320 CHECK_EVAL("1/,1", "10"); // ISSUE 151
321
322 // Test automatic detection of radix point when multiple choices are possible
323 CHECK_EVAL("1,234.567", "1234.567");
324 CHECK_EVAL("1.234,567", "1234.567");
325 CHECK_EVAL("1,2,3", "123");
326 CHECK_EVAL("1.2.3", "123");
327 CHECK_EVAL("1,234,567.89", "1234567.89");
328 CHECK_EVAL("1.234.567,89", "1234567.89");
329 CHECK_EVAL("1,234.567,89", "1234.56789");
330 CHECK_EVAL("1.234,567.89", "1234.56789");
331
332 settings->setRadixCharacter('.');
333
334 CHECK_EVAL("1+0.5", "1.5");
335 CHECK_EVAL("1+0,5", "6");
336 CHECK_EVAL("1/.1", "10");
337 CHECK_EVAL("1/,1", "1");
338 CHECK_EVAL("1,234.567", "1234.567");
339 CHECK_EVAL("1.234,567", "1.234567");
340 CHECK_EVAL("1,2,3", "123");
341 CHECK_EVAL("1.2.3", "123");
342 CHECK_EVAL("1,234,567.89", "1234567.89");
343 CHECK_EVAL("1.234.567,89", "123456789");
344 CHECK_EVAL("1,234.567,89", "1234.56789");
345 CHECK_EVAL("1.234,567.89", "123456789");
346
347 settings->setRadixCharacter(',');
348
349 CHECK_EVAL("1+0.5", "6");
350 CHECK_EVAL("1+0,5", "1.5");
351 CHECK_EVAL("1/.1", "1");
352 CHECK_EVAL("1/,1", "10");
353 CHECK_EVAL("1,234.567", "1.234567");
354 CHECK_EVAL("1.234,567", "1234.567");
355 CHECK_EVAL("1,2,3", "123");
356 CHECK_EVAL("1.2.3", "123");
357 CHECK_EVAL("1,234,567.89", "123456789");
358 CHECK_EVAL("1.234.567,89", "1234567.89");
359 CHECK_EVAL("1,234.567,89", "123456789");
360 CHECK_EVAL("1.234,567.89", "1234.56789");
361
362 // Restore old settings
363 settings->setRadixCharacter(radixCharacter);
364 }
365
test_thousand_sep()366 void test_thousand_sep()
367 {
368 CHECK_EVAL("12_345.678_9", "12345.6789");
369 CHECK_EVAL("1234_5.67_89", "12345.6789");
370 CHECK_EVAL("1234_56", "123456");
371 CHECK_EVAL("_123456", "123456");
372 CHECK_EVAL("123456_", "123456");
373 CHECK_EVAL("123___456", "123456");
374 CHECK_EVAL("._123456", "0.123456");
375
376 CHECK_EVAL("12 345.678 9", "12345.6789");
377 // CHECK_EVAL("12'345.678'9", "12345.6789");
378 CHECK_EVAL(QString::fromUtf8("12·345.678·9"), "12345.6789");
379 CHECK_EVAL(QString::fromUtf8("12٫345.678٫9"), "12345.6789");
380 CHECK_EVAL(QString::fromUtf8("12٬345.678٬9"), "12345.6789");
381 CHECK_EVAL(QString::fromUtf8("12˙345.678˙9"), "12345.6789");
382 CHECK_EVAL(QString::fromUtf8("12⎖345.678⎖9"), "12345.6789");
383
384 CHECK_EVAL("12$345.678~9", "12345.6789");
385 CHECK_EVAL("12`345.678@9", "12345.6789");
386 CHECK_EVAL("$ 1234.567", "1234.567");
387 CHECK_EVAL("1234.567 $", "1234.567");
388 CHECK_EVAL("$-10", "-10");
389 CHECK_EVAL("$+10", "10");
390 }
391
test_sexagesimal()392 void test_sexagesimal()
393 {
394 // Backup current settings
395 Settings* settings = Settings::instance();
396 char angleUnit = settings->angleUnit;
397 char resultFormat = settings->resultFormat;
398 int resultPrecision = settings->resultPrecision;
399
400 settings->angleUnit = 'd';
401 settings->resultFormat = 's';
402 settings->resultPrecision = 2;
403 Evaluator::instance()->initializeAngleUnits();
404
405 CHECK_EVAL_FORMAT_FAIL(":");
406 CHECK_EVAL_FORMAT_FAIL("::");
407 CHECK_EVAL_FORMAT_FAIL("0:::");
408 CHECK_EVAL_FORMAT_FAIL("1.2:34.56");
409 CHECK_EVAL_FORMAT_FAIL("12:3.4:56.78");
410
411 CHECK_EVAL_FORMAT("0:", "0:00:00");
412 CHECK_EVAL_FORMAT("::56", "0:00:56.00");
413 CHECK_EVAL_FORMAT("56 second", "0:00:56.00");
414 CHECK_EVAL_FORMAT(":34", "0:34:00.00");
415 CHECK_EVAL_FORMAT(":34:", "0:34:00.00");
416 CHECK_EVAL_FORMAT(":34.5:", "0:34:30.00");
417 CHECK_EVAL_FORMAT("34.5 minute", "0:34:30.00");
418 CHECK_EVAL_FORMAT("12:", "12:00:00.00");
419 CHECK_EVAL_FORMAT("12::", "12:00:00.00");
420 CHECK_EVAL_FORMAT("12.3:", "12:18:00.00");
421 CHECK_EVAL_FORMAT("12.3 hour", "12:18:00.00");
422 CHECK_EVAL_FORMAT("12:34", "12:34:00.00");
423 CHECK_EVAL_FORMAT("12:34:", "12:34:00.00");
424 CHECK_EVAL_FORMAT("12:34.", "12:34:00.00");
425 CHECK_EVAL_FORMAT("12:34.5", "12:34:30.00");
426 CHECK_EVAL_FORMAT("12:34:56", "12:34:56.00");
427 CHECK_EVAL_FORMAT("12:34:56.", "12:34:56.00");
428 CHECK_EVAL_FORMAT("12:34:56.78", "12:34:56.78");
429
430 CHECK_EVAL_FORMAT("-0:", "0:00:00");
431 CHECK_EVAL_FORMAT("-::56", "-0:00:56.00");
432 CHECK_EVAL_FORMAT("-:34", "-0:34:00.00");
433 CHECK_EVAL_FORMAT("-12:", "-12:00:00.00");
434 CHECK_EVAL_FORMAT("-12:34", "-12:34:00.00");
435 CHECK_EVAL_FORMAT("-12:34.5", "-12:34:30.00");
436 CHECK_EVAL_FORMAT("-12:34:56", "-12:34:56.00");
437 CHECK_EVAL_FORMAT("-12:34:56.78", "-12:34:56.78");
438
439 CHECK_EVAL_FORMAT_FAIL("°");
440 CHECK_EVAL_FORMAT_FAIL("°'");
441 CHECK_EVAL_FORMAT_FAIL("°0\"");
442 CHECK_EVAL_FORMAT_FAIL("1.2°34.56");
443 CHECK_EVAL_FORMAT_FAIL("12°3.4'56.78\"");
444
445 CHECK_EVAL_FORMAT_FAIL("56\"7");
446 CHECK_EVAL_FORMAT_FAIL("56.78\"9");
447 CHECK_EVAL_FORMAT_FAIL("34'\"5");
448 CHECK_EVAL_FORMAT_FAIL("12°'\"3");
449 CHECK_EVAL_FORMAT_FAIL("12°34'56.78\"9");
450
451 CHECK_EVAL_FORMAT("0", "0°00'00");
452 CHECK_EVAL_FORMAT("°'56", "0°00'56.00");
453 CHECK_EVAL_FORMAT("'56", "0°00'56.00");
454 CHECK_EVAL_FORMAT("56\"", "0°00'56.00");
455 CHECK_EVAL_FORMAT("56 arcsecond", "0°00'56.00");
456 CHECK_EVAL_FORMAT("56.78\"", "0°00'56.78");
457 CHECK_EVAL_FORMAT("°34", "0°34'00.00");
458 CHECK_EVAL_FORMAT("34'", "0°34'00.00");
459 CHECK_EVAL_FORMAT("34.5'", "0°34'30.00");
460 CHECK_EVAL_FORMAT("34'\"", "0°34'00.00");
461 CHECK_EVAL_FORMAT("34.5'\"", "0°34'30.00");
462 CHECK_EVAL_FORMAT("34.5 arcminute", "0°34'30.00");
463 CHECK_EVAL_FORMAT("34'56", "0°34'56.00");
464 CHECK_EVAL_FORMAT("12°", "12°00'00.00");
465 CHECK_EVAL_FORMAT("12°'", "12°00'00.00");
466 CHECK_EVAL_FORMAT("12°'\"", "12°00'00.00");
467 CHECK_EVAL_FORMAT("12.3°", "12°18'00.00");
468 CHECK_EVAL_FORMAT("12.3°'", "12°18'00.00");
469 CHECK_EVAL_FORMAT("12.3°'\"", "12°18'00.00");
470 CHECK_EVAL_FORMAT("12°34", "12°34'00.00");
471 CHECK_EVAL_FORMAT("12°34'", "12°34'00.00");
472 CHECK_EVAL_FORMAT("12°34.", "12°34'00.00");
473 CHECK_EVAL_FORMAT("12°34.5", "12°34'30.00");
474 CHECK_EVAL_FORMAT("12°34.5'", "12°34'30.00");
475 CHECK_EVAL_FORMAT("12°34'56", "12°34'56.00");
476 CHECK_EVAL_FORMAT("12°34'56.", "12°34'56.00");
477 CHECK_EVAL_FORMAT("12°34'56.78", "12°34'56.78");
478 CHECK_EVAL_FORMAT("12°34'56.78\"", "12°34'56.78");
479
480 CHECK_EVAL_FORMAT("-0", "0°00'00");
481 CHECK_EVAL_FORMAT("-°'56", "-0°00'56.00");
482 CHECK_EVAL_FORMAT("-56\"", "-0°00'56.00");
483 CHECK_EVAL_FORMAT("-°34", "-0°34'00.00");
484 CHECK_EVAL_FORMAT("-34'", "-0°34'00.00");
485 CHECK_EVAL_FORMAT("-12°", "-12°00'00.00");
486 CHECK_EVAL_FORMAT("-12.3°", "-12°18'00.00");
487 CHECK_EVAL_FORMAT("-12°34", "-12°34'00.00");
488 CHECK_EVAL_FORMAT("-12°34.5", "-12°34'30.00");
489 CHECK_EVAL_FORMAT("-12°34'56", "-12°34'56.00");
490 CHECK_EVAL_FORMAT("-12°34'56.78", "-12°34'56.78");
491 CHECK_EVAL_FORMAT("-12°34'56.78\"", "-12°34'56.78");
492
493 settings->angleUnit = 'g';
494 Evaluator::instance()->initializeAngleUnits();
495
496 CHECK_EVAL_FORMAT("100.5", "90°27'00.00");
497 CHECK_EVAL_FORMAT("-200.3", "-180°16'12.00");
498 CHECK_EVAL_FORMAT("12.3 degree", "12°18'00.00");
499
500 settings->angleUnit = 'r';
501 Evaluator::instance()->initializeAngleUnits();
502
503 CHECK_EVAL_FORMAT("pi", "180°00'00.00");
504 CHECK_EVAL_FORMAT("-pi", "-180°00'00.00");
505 CHECK_EVAL_FORMAT("12.3 degree", "12°18'00.00");
506
507 settings->resultPrecision = 32;
508
509 CHECK_EVAL_FORMAT("::56.78901234567890123456789012345678", "0:00:56.78901234567890123456789012345678");
510 CHECK_EVAL_FORMAT(":34.56789012345678901234567890123456", "0:34:34.07340740740734074074073407407360");
511 CHECK_EVAL_FORMAT("12.34567890123456789012345678901234:", "12:20:44.44404444444440444444444044442400");
512
513 settings->angleUnit = 'd';
514 Evaluator::instance()->initializeAngleUnits();
515
516 CHECK_EVAL_FORMAT("56.78901234567890123456789012345678\"", "0°00'56.78901234567890123456789012345678");
517 CHECK_EVAL_FORMAT("34.56789012345678901234567890123456'", "0°34'34.07340740740734074074073407407360");
518 CHECK_EVAL_FORMAT("12.34567890123456789012345678901234°", "12°20'44.44404444444440444444444044442400");
519
520 // Restore old settings
521 settings->angleUnit = angleUnit;
522 settings->resultFormat = resultFormat;
523 settings->resultPrecision = resultPrecision;
524 Evaluator::instance()->initializeAngleUnits();
525 }
526
test_function_basic()527 void test_function_basic()
528 {
529 CHECK_EVAL("ABS(0)", "0");
530 CHECK_EVAL("ABS(1)", "1");
531 CHECK_EVAL("ABS(-1)", "1");
532 CHECK_EVAL("ABS(--1)", "1");
533 CHECK_EVAL("ABS(---1)", "1");
534 CHECK_EVAL("ABS((1))", "1");
535 CHECK_EVAL("ABS((-1))", "1");
536
537 CHECK_EVAL("ABS(1/2)", "0.5");
538 CHECK_EVAL("ABS(-1/2)", "0.5");
539 CHECK_EVAL("ABS(-1/-2)", "0.5");
540 CHECK_EVAL("ABS(1/-2)", "0.5");
541
542 CHECK_EVAL("INT(0)", "0");
543 CHECK_EVAL("INT(1)", "1");
544 CHECK_EVAL("INT(-1)", "-1");
545 CHECK_EVAL("INT(0.5)", "0");
546 CHECK_EVAL("INT(-0.75)", "0");
547 CHECK_EVAL("INT(-0.9999*1)", "0");
548 CHECK_EVAL("INT(0.9999*1)", "0");
549 CHECK_EVAL("INT(2.1)", "2");
550 CHECK_EVAL("INT(-3.4)", "-3");
551
552 CHECK_EVAL("log(0.123; 0.1234)", "0.99845065797473594741");
553 CHECK_EVAL("lg(0.00000000001)", "-11");
554 CHECK_EVAL("lg(1e-3)", "-3");
555 CHECK_EVAL("lb(0.00000000001)", "-36.54120904376098582657");
556 CHECK_EVAL("lb(32)", "5");
557 CHECK_EVAL("ln(100)", "4.60517018598809136804");
558 CHECK_EVAL("ln(4.0)", "1.38629436111989061883");
559
560 CHECK_EVAL("0!", "1");
561 CHECK_EVAL("1!", "1");
562 CHECK_EVAL("2!", "2");
563 CHECK_EVAL("3!", "6");
564 CHECK_EVAL("4!", "24");
565 CHECK_EVAL("5!", "120");
566 CHECK_EVAL("6!", "720");
567 CHECK_EVAL("7!", "5040");
568 CHECK_EVAL("(1+1)!^2", "4");
569
570 CHECK_EVAL("(-27)^(1/3)", "-3");
571 CHECK_EVAL("(-27)^(-1/3)", "-0.33333333333333333333");
572
573 CHECK_EVAL_PRECISE("exp((1)/2) + exp((1)/2)", "3.29744254140025629369730157562832714330755220142030");
574
575 // Test functions composition
576 CHECK_EVAL("log(10;log(10;1e100))", "2");
577 CHECK_EVAL("log(10;abs(-100))", "2");
578 CHECK_EVAL("abs(log(10;100))", "2");
579 CHECK_EVAL("abs(abs(-100))", "100");
580 CHECK_EVAL("sum(10;abs(-100);1)", "111");
581 CHECK_EVAL("sum(abs(-100);10;1)", "111");
582 CHECK_EVAL("sum(10;1;abs(-100))", "111");
583 }
584
test_function_trig()585 void test_function_trig()
586 {
587 CHECK_EVAL_PRECISE("pi", "3.14159265358979323846264338327950288419716939937511");
588
589 CHECK_EVAL("sin(0)", "0");
590 CHECK_EVAL("cos(0)", "1");
591 CHECK_EVAL("tan(0)", "0");
592
593 CHECK_EVAL("sin(pi)", "0");
594 CHECK_EVAL("cos(pi)", "-1");
595 CHECK_EVAL("tan(pi)", "0");
596
597 CHECK_EVAL("sin(-pi)", "0");
598 CHECK_EVAL("cos(-pi)", "-1");
599 CHECK_EVAL("tan(-pi)", "0");
600
601 CHECK_EVAL("sin(--pi)", "0");
602 CHECK_EVAL("cos(--pi)", "-1");
603 CHECK_EVAL("tan(--pi)", "0");
604
605 CHECK_EVAL("sin(pi/2)", "1");
606 CHECK_EVAL("cos(pi/2)", "0");
607
608 CHECK_EVAL("sin(-pi/2)", "-1");
609 CHECK_EVAL("cos(-pi/2)", "0");
610
611 CHECK_EVAL("sin(-pi/2) + sin(pi/2)", "0");
612 CHECK_EVAL("sin(-pi/2) - sin(pi/2)", "-2");
613 CHECK_EVAL("cos(-pi/2) + cos(pi/2)", "0");
614 CHECK_EVAL("cos(-pi/2) - cos(pi/2)", "0");
615
616 CHECK_EVAL("arcsin(sin(1))", "1");
617 CHECK_EVAL("arccos(cos(1))", "1");
618 CHECK_EVAL("arctan(tan(1))", "1");
619 CHECK_EVAL("arcsin(0)", "0");
620 CHECK_EVAL("arccos(1)", "0");
621 CHECK_EVAL("arctan(0)", "0");
622
623 CHECK_EVAL("degrees(0)", "0");
624 CHECK_EVAL("degrees(pi/2)", "90");
625 CHECK_EVAL("degrees(pi)", "180");
626 CHECK_EVAL("degrees(3*pi/2)", "270");
627 CHECK_EVAL("degrees(2*pi)", "360");
628
629 CHECK_EVAL("radians(0)", "0");
630 CHECK_EVAL("radians(90)/pi", "0.5");
631 CHECK_EVAL("radians(180)/pi", "1");
632 CHECK_EVAL("radians(270)/pi", "1.5");
633 CHECK_EVAL("radians(360)/pi", "2");
634
635 CHECK_EVAL("gradians(0)", "0");
636 CHECK_EVAL("gradians(pi/2)", "100");
637 CHECK_EVAL("gradians(pi)", "200");
638 CHECK_EVAL("gradians(3*pi/2)", "300");
639 CHECK_EVAL("gradians(2*pi)", "400");
640 }
641
test_function_stat()642 void test_function_stat()
643 {
644 CHECK_EVAL_FAIL("MIN(0)");
645 CHECK_EVAL("MIN(0; 1)", "0");
646 CHECK_EVAL("MIN(0; 2)", "0");
647 CHECK_EVAL("MIN(-1; 0)", "-1");
648 CHECK_EVAL("MIN(-1; 1)", "-1");
649 CHECK_EVAL("MIN(-0.01; 0)", "-0.01");
650 CHECK_EVAL("MIN(0; 1; 2)", "0");
651 CHECK_EVAL("MIN(-1; 0; 1; 2)", "-1");
652 CHECK_EVAL("MIN(-2; -1; 0; 1; 2)", "-2");
653
654 CHECK_EVAL_FAIL("MAX(0)");
655 CHECK_EVAL("MAX(0; 1)", "1");
656 CHECK_EVAL("MAX(0; 2)", "2");
657 CHECK_EVAL("MAX(-1; 0)", "0");
658 CHECK_EVAL("MAX(-1; 1)", "1");
659 CHECK_EVAL("MAX(0.01; 0)", "0.01");
660 CHECK_EVAL("MAX(0; 1; 2)", "2");
661 CHECK_EVAL("MAX(-1; 0; 1; 2)", "2");
662 CHECK_EVAL("MAX(-2; -1; 0; 1; 2)", "2");
663
664 CHECK_EVAL_FAIL("SUM(1)");
665 CHECK_EVAL("SUM(100;1)", "101");
666 CHECK_EVAL("SUM(-100;1)", "-99");
667 CHECK_EVAL("SUM(0;0;0)", "0");
668 CHECK_EVAL("SUM(100;-1)", "99");
669 CHECK_EVAL("SUM(-100;-1)", "-101");
670 CHECK_EVAL("SUM(1;2;3;4;5;6)", "21");
671 CHECK_EVAL("SUM(1;-2;3;-4;5;-6)", "-3");
672
673 CHECK_EVAL_FAIL("PRODUCT(-1)");
674 CHECK_EVAL("PRODUCT(100;0)", "0");
675 CHECK_EVAL("PRODUCT(100;1)", "100");
676 CHECK_EVAL("PRODUCT(-100;1)", "-100");
677 CHECK_EVAL("PRODUCT(-100;-1)", "100");
678 CHECK_EVAL("PRODUCT(1;1;1)", "1");
679 CHECK_EVAL("PRODUCT(1;2;3;4;5;6)", "720");
680 CHECK_EVAL("PRODUCT(1;-2;3;-4;5;-6)", "-720");
681
682 CHECK_EVAL_FAIL("AVERAGE(0)");
683 CHECK_EVAL("AVERAGE(0;0)", "0");
684 CHECK_EVAL("AVERAGE(0;0;0)", "0");
685 CHECK_EVAL("AVERAGE(0;1)", "0.5");
686 CHECK_EVAL("AVERAGE(0;1;2)", "1");
687 CHECK_EVAL("AVERAGE(0;1;0)*3", "1");
688 CHECK_EVAL("AVERAGE(1;1;1)", "1");
689 CHECK_EVAL("AVERAGE(2;2;2)", "2");
690 CHECK_EVAL("AVERAGE(3;3;3)", "3");
691 CHECK_EVAL("AVERAGE(0.25;0.75)", "0.5");
692 CHECK_EVAL("AVERAGE(2.25;4.75)", "3.5");
693 CHECK_EVAL("AVERAGE(1/3;2/3)", "0.5");
694
695 CHECK_EVAL_FAIL("GEOMEAN(-1e20;0;-1)");
696 CHECK_EVAL_FAIL("GEOMEAN(5)");
697 CHECK_EVAL("GEOMEAN(1;1)", "1");
698 CHECK_EVAL("GEOMEAN(1;4)", "2");
699 CHECK_EVAL("GEOMEAN(4;9)", "6");
700 CHECK_EVAL("GEOMEAN(3.6;8.1)", "5.4");
701 CHECK_EVAL("GEOMEAN(3;4;18)", "6");
702 CHECK_EVAL("GEOMEAN(1;1;1)", "1");
703 CHECK_EVAL("GEOMEAN(1;1;1;1)", "1");
704 CHECK_EVAL_FAIL("GEOMEAN(1;1;1;-1)");
705
706 CHECK_EVAL("VARIANCE(1;-1)", "1");
707 CHECK_EVAL("VARIANCE(5 meter; 13 meter)", "16 meter²");
708 // for complex tests of VARIANCE see test_complex
709 }
710
test_function_logic()711 void test_function_logic()
712 {
713 CHECK_EVAL_FAIL("and(1)");
714 CHECK_EVAL_FAIL("or(2)");
715 CHECK_EVAL_FAIL("xor(3)");
716
717 CHECK_EVAL("and(0;0)", "0");
718 CHECK_EVAL("and(0;1)", "0");
719 CHECK_EVAL("and(1;0)", "0");
720 CHECK_EVAL("and(1;1)", "1");
721
722 CHECK_EVAL("or(0;0)", "0");
723 CHECK_EVAL("or(0;1)", "1");
724 CHECK_EVAL("or(1;0)", "1");
725 CHECK_EVAL("or(1;1)", "1");
726
727 CHECK_EVAL("xor(0;0)", "0");
728 CHECK_EVAL("xor(0;1)", "1");
729 CHECK_EVAL("xor(1;0)", "1");
730 CHECK_EVAL("xor(1;1)", "0");
731 }
732
test_function_discrete()733 void test_function_discrete()
734 {
735 CHECK_EVAL("gcd(12;18)", "6");
736 CHECK_EVAL("gcd(36;56;210)", "2");
737 CHECK_EVAL("gcd(28;120;126)", "2");
738
739 CHECK_EVAL("ncr(-3;-1)", "0");
740 CHECK_EVAL("ncr(-3;0)", "1");
741 CHECK_EVAL("ncr(-3;1)", "-3");
742 CHECK_EVAL("ncr(-3;2)", "6");
743 CHECK_EVAL("ncr(-3;3)", "-10");
744 CHECK_EVAL("ncr(-3;4)", "15");
745 CHECK_EVAL("ncr(-3;5)", "-21");
746 CHECK_EVAL("ncr(-2;-1)", "0");
747 CHECK_EVAL("ncr(-2;0)", "1");
748 CHECK_EVAL("ncr(-2;1)", "-2");
749 CHECK_EVAL("ncr(-2;2)", "3");
750 CHECK_EVAL("ncr(-2;3)", "-4");
751 CHECK_EVAL("ncr(-2;4)", "5");
752 CHECK_EVAL("ncr(-2;5)", "-6");
753
754 CHECK_EVAL("ncr(-1;-1)", "0");
755 CHECK_EVAL("ncr(-1;0)", "1");
756 CHECK_EVAL("ncr(-1;1)", "-1");
757 CHECK_EVAL("ncr(-1;2)", "1");
758 CHECK_EVAL("ncr(-1;3)", "-1");
759 CHECK_EVAL("ncr(-1;4)", "1");
760 CHECK_EVAL("ncr(-1;5)", "-1");
761
762 CHECK_EVAL("ncr(0;-1)", "0");
763 CHECK_EVAL("ncr(0;0)", "1");
764 CHECK_EVAL("ncr(0;1)", "0");
765
766 CHECK_EVAL("ncr(1;-1)", "0");
767 CHECK_EVAL("ncr(1;0)", "1");
768 CHECK_EVAL("ncr(1;1)", "1");
769 CHECK_EVAL("ncr(1;2)", "0");
770
771 CHECK_EVAL("ncr(2;-1)", "0");
772 CHECK_EVAL("ncr(2;0)", "1");
773 CHECK_EVAL("ncr(2;1)", "2");
774 CHECK_EVAL("ncr(2;2)", "1");
775 CHECK_EVAL("ncr(2;3)", "0");
776
777 CHECK_EVAL("ncr(3;-1)", "0");
778 CHECK_EVAL("ncr(3;0)", "1");
779 CHECK_EVAL("ncr(3;1)", "3");
780 CHECK_EVAL("ncr(3;2)", "3");
781 CHECK_EVAL("ncr(3;3)", "1");
782 CHECK_EVAL("ncr(3;4)", "0");
783
784 CHECK_EVAL("ncr(4;-1)", "0");
785 CHECK_EVAL("ncr(4;0)", "1");
786 CHECK_EVAL("ncr(4;1)", "4");
787 CHECK_EVAL("ncr(4;2)", "6");
788 CHECK_EVAL("ncr(4;3)", "4");
789 CHECK_EVAL("ncr(4;4)", "1");
790 CHECK_EVAL("ncr(4;5)", "0");
791 }
792
test_function_simplified()793 void test_function_simplified()
794 {
795 /* Tests for standard functions */
796 CHECK_EVAL("abs 123", "123");
797 CHECK_EVAL("abs -123", "123"); /* (issue #600) */
798 CHECK_EVAL("10 + abs 123", "133");
799 CHECK_EVAL("10 + abs -123", "133"); /* (issue #600) */
800 CHECK_EVAL("abs 123 + 10", "133");
801 CHECK_EVAL("abs -123 + 10", "133"); /* (issue #600) */
802 CHECK_EVAL("10 * abs 123", "1230");
803 CHECK_EVAL("abs 123 * 10", "1230");
804 /* Tests for user functions (issue #600, cf. discussion) */
805 CHECK_USERFUNC_SET("func2(x) = abs(x)");
806 CHECK_EVAL("func2 123", "123");
807 CHECK_EVAL("func2 -123", "123");
808 CHECK_EVAL("10 + func2 123", "133");
809 CHECK_EVAL("10 + func2 -123", "133");
810 CHECK_EVAL("func2 123 + 10", "133");
811 CHECK_EVAL("func2 -123 + 10", "133");
812 CHECK_EVAL("10 * func2 123", "1230");
813 CHECK_EVAL("func2 123 * 10", "1230");
814 CHECK_USERFUNC_SET("f(x) = 5 meter + x"); /* (issue #656) */
815 CHECK_EVAL("f(2 meter)", "7 meter"); /* (issue #656) */
816 CHECK_EVAL_FAIL("f(2)"); /* (issue #656) */
817 /* Tests for priority management (issue #451) */
818 CHECK_EVAL("lg 10^2", "2");
819 CHECK_EVAL("frac 3!", "0");
820 }
821
test_auto_fix_parentheses()822 void test_auto_fix_parentheses()
823 {
824 CHECK_AUTOFIX("sin(1)", "sin(1)");
825 CHECK_AUTOFIX("sin(1", "sin(1)");
826
827 CHECK_AUTOFIX("x+(8-2", "x+(8-2)");
828 CHECK_AUTOFIX("x+(8-2)", "x+(8-2)");
829
830 CHECK_AUTOFIX("x+(8-(2*1", "x+(8-(2*1))");
831 CHECK_AUTOFIX("x+(8-(2*1)", "x+(8-(2*1))");
832 CHECK_AUTOFIX("x+(8-(2*1))", "x+(8-(2*1))");
833
834 CHECK_AUTOFIX("x + sin (pi", "x + sin (pi)");
835 }
836
test_auto_fix_ans()837 void test_auto_fix_ans()
838 {
839 CHECK_AUTOFIX("sin", "sin(ans)");
840 CHECK_AUTOFIX("cos", "cos(ans)");
841 CHECK_AUTOFIX("tan", "tan(ans)");
842 CHECK_AUTOFIX("abs", "abs(ans)");
843 CHECK_AUTOFIX("exp", "exp(ans)");
844 CHECK_AUTOFIX("lg", "lg(ans)");
845 }
846
test_auto_fix_trailing_equal()847 void test_auto_fix_trailing_equal()
848 {
849 CHECK_AUTOFIX("1+2=", "1+2");
850 CHECK_AUTOFIX("1==", "1");
851 CHECK_AUTOFIX("1/3====", "1/3");
852 CHECK_AUTOFIX("sin(x+y)=", "sin(x+y)");
853 }
854
test_auto_fix_untouch()855 void test_auto_fix_untouch()
856 {
857 CHECK_AUTOFIX("sin(x)", "sin(x)");
858 CHECK_AUTOFIX("sin((x/y))", "sin((x/y))");
859 CHECK_AUTOFIX("ans", "ans");
860 CHECK_AUTOFIX("sin(ans)", "sin(ans)");
861 CHECK_AUTOFIX("tan(ans)", "tan(ans)");
862 CHECK_AUTOFIX("x=1.2", "x=1.2");
863 CHECK_AUTOFIX("1/sin pi", "1/sin pi");
864 }
865
test_auto_fix_powers()866 void test_auto_fix_powers()
867 {
868 CHECK_AUTOFIX("3¹", "3^1");
869 CHECK_AUTOFIX("3⁻¹", "3^(-1)");
870 CHECK_AUTOFIX("3¹²³⁴⁵⁶⁷⁸⁹", "3^123456789");
871 CHECK_AUTOFIX("3²⁰", "3^20");
872 CHECK_AUTOFIX("7 + 3²⁰ * 4", "7 + 3^20 * 4");
873 }
874
test_comments()875 void test_comments()
876 {
877 CHECK_EVAL("ncr(3;3) ? this is because foo", "1");
878 }
879
test_user_functions()880 void test_user_functions()
881 {
882 // Check user functions can be defined and used
883 CHECK_USERFUNC_SET("func1(a;b) = a * b + 10");
884 CHECK_EVAL("func1(2;5)", "20"); // = 2 * 5 + 10
885 // Check some expected error conditions
886 CHECK_EVAL_FAIL("func1()");
887 CHECK_EVAL_FAIL("func1(2)");
888 CHECK_EVAL_FAIL("func1(2;5;1)");
889
890 // Check user functions can call other user functions
891 CHECK_USERFUNC_SET("func2(a;b) = func1(a;b) - 10");
892 CHECK_EVAL("func2(2;5)", "10"); // = (2 * 5 + 10) - 10
893
894 // Check user functions can be redefined
895 CHECK_USERFUNC_SET("func2(a;b) = 10 + func1(a;b)");
896 CHECK_EVAL("func2(2;5)", "30"); // = 10 + (2 * 5 + 10)
897
898 // Check user functions can refer to other user functions not defined
899 CHECK_USERFUNC_SET("func2(a;b) = 10 * a + func3(a;b)");
900 CHECK_EVAL_FAIL("func2(2;5)");
901 CHECK_USERFUNC_SET("func3(a;b) = a - b");
902 CHECK_EVAL("func2(2;5)", "17"); // = 10 * 2 + (2 - 5)
903
904 // Check user functions can call builtin functions
905 CHECK_USERFUNC_SET("func2(a;b) = sum(func1(a;b);5)");
906 CHECK_EVAL("func2(2;5)", "25"); // = sum((2 * 5 + 10);5)
907
908 // Check recursive user functions are not allowed
909 CHECK_USERFUNC_SET("func_r(a) = a * func_r(a)");
910 CHECK_EVAL_FAIL("func_r(1)");
911 CHECK_USERFUNC_SET("func_r1(a) = a * func_r2(a)");
912 CHECK_USERFUNC_SET("func_r2(a) = a + func_r1(a)");
913 CHECK_EVAL_FAIL("func_r1(1)");
914
915 // Check user functions can refer to user variables
916 CHECK_USERFUNC_SET("func1(a;b) = a * b - var1");
917 CHECK_EVAL_FAIL("func1(2;5)");
918 CHECK_EVAL("var1 = 5", "5");
919 CHECK_EVAL("func1(2;5)", "5"); // = 2 * 5 - 5
920
921 // Check conflicts between the names of user functions arguments and user variables
922 CHECK_EVAL("arg1 = 10", "10");
923 CHECK_USERFUNC_SET("func1(arg1;arg2) = arg1 * arg2");
924 CHECK_EVAL("func1(2;5)", "10"); // = 2 * 5 (not 10 * 5)
925
926 // Check user functions names can not mask builtin functions
927 CHECK_USERFUNC_SET_FAIL("sum(a;b) = a * b");
928
929 // Check user functions names can not mask user variables
930 CHECK_EVAL("var1 = 5", "5");
931 CHECK_USERFUNC_SET_FAIL("var1(a;b) = a * b");
932
933 // Check user functions can take no argument
934 CHECK_EVAL("func1() = 2 * 10", "20");
935 // NOTE: we use CHECK_EVAL to define the function, because its result is known at definition
936 // time. CHECK_USERFUNC_SET expects NaN, which is what is returned when the function body
937 // contains at least one component whose value can not be known at definition time
938 // (e.g., reference to user function arguments or to user/builtin functions).
939 CHECK_EVAL("func1()", "20"); // = 2 * 5
940 }
941
test_complex()942 void test_complex()
943 {
944 // Check for basic complex number processing
945 CHECK_EVAL("1j", "1j");
946 CHECK_EVAL("0.1j", "0.1j");
947 CHECK_EVAL(".1j", "0.1j");
948 CHECK_EVAL("1E12j", "1000000000000j");
949 CHECK_EVAL("0.1E12j", "100000000000j");
950 CHECK_EVAL("1E-12j", "0.000000000001j");
951 CHECK_EVAL("0.1E-12j", "0.0000000000001j");
952 // Check for some bugs introduced by first versions of complex number processing
953 CHECK_EVAL("0.1", "0.1");
954 // Check for basic complex number evaluation
955 CHECK_EVAL("(1+1j)*(1-1j)", "2");
956 CHECK_EVAL("(1+1j)*(1+1j)", "2j");
957
958
959 CHECK_EVAL("VARIANCE(1j;-1j)", "1");
960 CHECK_EVAL("VARIANCE(1j;-1j;1;-1)", "1");
961 CHECK_EVAL("VARIANCE(2j;-2j;1;-1)", "2.5");
962 }
963
test_angle_mode(Settings * settings)964 void test_angle_mode(Settings* settings)
965 {
966 settings->angleUnit = 'r';
967 Evaluator::instance()->initializeAngleUnits();
968 CHECK_EVAL("sin(pi)", "0");
969 CHECK_EVAL("arcsin(-1)", "-1.57079632679489661923");
970 CHECK_EVAL("sin(1j)", "1.17520119364380145688j");
971 CHECK_EVAL("arcsin(-2)", "-1.57079632679489661923+1.31695789692481670863j");
972 CHECK_EVAL("radian","1");
973 CHECK_EVAL("degree","0.01745329251994329577");
974 CHECK_EVAL("gradian","0.01570796326794896619");
975 CHECK_EVAL("gon","0.01570796326794896619");
976
977 settings->angleUnit = 'd';
978 Evaluator::instance()->initializeAngleUnits();
979 CHECK_EVAL("sin(180)", "0");
980 CHECK_EVAL("arcsin(-1)", "-90");
981 CHECK_EVAL_FAIL("sin(1j)");
982 CHECK_EVAL("arcsin(-2)", "-90+75.4561292902168920041j");
983 CHECK_EVAL("radian","57.2957795130823208768");
984 CHECK_EVAL("degree","1");
985 CHECK_EVAL("gradian","0.9");
986 CHECK_EVAL("gon","0.9");
987 CHECK_EVAL_KNOWN_ISSUE("arcsin(0.25)", "14.47751218592992387877", 781);
988
989 settings->angleUnit = 'g';
990 Evaluator::instance()->initializeAngleUnits();
991 CHECK_EVAL("sin(200)", "0");
992 CHECK_EVAL("arcsin(-1)", "-100");
993 CHECK_EVAL_FAIL("sin(1j)");
994 CHECK_EVAL("arcsin(-2)", "-100+83.84014365579654667122j");
995 CHECK_EVAL("radian","63.66197723675813430755");
996 CHECK_EVAL("degree","1.11111111111111111111");
997 CHECK_EVAL("gradian","1");
998 CHECK_EVAL("gon","1");
999 }
1000
test_implicit_multiplication()1001 void test_implicit_multiplication()
1002 {
1003 CHECK_EVAL("a = 5", "5");
1004 CHECK_EVAL("5a", "25");
1005 CHECK_EVAL("5.a", "25");
1006 CHECK_EVAL("5.0a", "25");
1007 CHECK_EVAL("5e2a", "2500");
1008 CHECK_EVAL_FAIL("a5");
1009 CHECK_EVAL("a 5", "25");
1010 CHECK_EVAL("2a^3", "250");
1011 CHECK_EVAL("b=2", "2");
1012 CHECK_EVAL_FAIL("ab");
1013 CHECK_EVAL("a b", "10");
1014 CHECK_EVAL("eps = 10", "10");
1015 CHECK_EVAL("5 eps", "50");
1016 CHECK_EVAL("Eren = 1001", "1001");
1017 CHECK_EVAL("7 Eren", "7007");
1018 CHECK_EVAL("Eren 5", "5005");
1019 CHECK_EVAL("f() = 123", "123");
1020 CHECK_EVAL("2f()", "246");
1021 CHECK_EVAL("5 5", "55");
1022
1023 // Check implicit multiplication between numbers fails
1024 // CHECK_EVAL_FAIL("10. 0.2");
1025 CHECK_EVAL_FAIL("10 0x10");
1026 CHECK_EVAL_FAIL("10 #10");
1027 CHECK_EVAL_FAIL("0b104");
1028 CHECK_EVAL_FAIL("0b10 4");
1029 CHECK_EVAL_FAIL("0b10 0x4");
1030 CHECK_EVAL_FAIL("0o109");
1031 CHECK_EVAL_FAIL("0o10 9");
1032 CHECK_EVAL_FAIL("0o10 0x9");
1033 // CHECK_EVAL_FAIL("12.12.12");
1034 CHECK_EVAL_FAIL("12e12.12");
1035 CHECK_EVAL("0b10a", "10");
1036 CHECK_EVAL("0o2a", "10");
1037 CHECK_EVAL("5(5)", "25");
1038
1039 CHECK_EVAL("a sin(pi/2)", "5");
1040 CHECK_EVAL("a sqrt(4)", "10");
1041 CHECK_EVAL("a sqrt(a^2)", "25");
1042
1043 /* Tests issue 538 */
1044 /* 3 sin (3 pi) was evaluated but not 3 sin (3) */
1045 CHECK_EVAL("3 sin (3 pi)", "0");
1046 CHECK_EVAL("3 sin (3)", "0.4233600241796016663");
1047
1048 CHECK_EVAL("2 (2 + 1)", "6");
1049 CHECK_EVAL("2 (a)", "10");
1050
1051 /* Tests issue 598 */
1052 CHECK_EVAL("2(a)^3", "250");
1053
1054 CHECK_EVAL_KNOWN_ISSUE("6/2(2+1)", "9", 741);
1055 CHECK_EVAL_KNOWN_ISSUE("2^2(2)", "8", 741);
1056 CHECK_EVAL_KNOWN_ISSUE("2^2(2)(2)", "16", 741);
1057 CHECK_EVAL_KNOWN_ISSUE("2^2(2*2)", "16", 741);
1058 CHECK_EVAL_KNOWN_ISSUE("2^2(2)+3", "11", 741);
1059 CHECK_EVAL_FAIL("pi (2)");
1060 }
1061
test_format()1062 void test_format()
1063 {
1064 CHECK_EVAL("bin(123)", "0b1111011");
1065 CHECK_EVAL("oct(123)", "0o173");
1066 CHECK_EVAL("hex(123)", "0x7B");
1067
1068 CHECK_EVAL("polar(3+4j)", "5 * exp(j*0.92729521800161223243)");
1069 }
1070
1071
test_datetime()1072 void test_datetime()
1073 {
1074 // NOTE We cannot test datetime() with only 1 argument as it depends on current timezone (and DST?)
1075
1076 CHECK_EVAL("datetime(1538242871; 0)", "20180929.174111");
1077 CHECK_EVAL("datetime(1514761200; 1)", "20180101.000000");
1078 CHECK_EVAL("datetime(1514764800; -1)", "20171231.230000");
1079 CHECK_EVAL("datetime(1551464695;13.75)", "20190302.080955"); // GMT +13:45
1080 CHECK_EVAL("datetime(1551464695; -3.5)", "20190301.145455"); // GMT -03:30
1081 }
1082
1083
main(int argc,char * argv[])1084 int main(int argc, char* argv[])
1085 {
1086 QCoreApplication app(argc, argv);
1087
1088 Settings* settings = Settings::instance();
1089 settings->angleUnit = 'r';
1090 settings->setRadixCharacter('.');
1091 settings->complexNumbers = false;
1092 DMath::complexMode = false;
1093
1094 eval = Evaluator::instance();
1095
1096 eval->initializeBuiltInVariables();
1097
1098 test_constants();
1099 test_exponentiation();
1100 test_unary();
1101 test_binary();
1102
1103 test_divide_by_zero();
1104 test_radix_char();
1105
1106 test_thousand_sep();
1107 test_sexagesimal();
1108
1109 test_function_basic();
1110 test_function_trig();
1111 test_function_stat();
1112 test_function_logic();
1113 test_function_discrete();
1114 test_function_simplified();
1115
1116 test_auto_fix_parentheses();
1117 test_auto_fix_ans();
1118 test_auto_fix_trailing_equal();
1119 test_auto_fix_powers();
1120 test_auto_fix_untouch();
1121
1122 test_comments();
1123
1124 test_user_functions();
1125
1126 test_implicit_multiplication();
1127
1128 settings->complexNumbers = true;
1129 DMath::complexMode = true;
1130 eval->initializeBuiltInVariables();
1131 test_complex();
1132 test_format();
1133 test_datetime();
1134
1135 test_angle_mode(settings);
1136
1137 if (!eval_failed_tests) {
1138 cout << "All tests succeed" << endl;
1139 return 0;
1140 }
1141
1142 cout << eval_total_tests << " total, "
1143 << eval_failed_tests << " failed, "
1144 << eval_new_failed_tests << " new" << endl;
1145 return eval_new_failed_tests;
1146 }
1147