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