File indexing completed on 2024-05-12 16:35:59
0001 /* This file is part of the KDE project 0002 Copyright 2007 Brad Hards <bradh@frogmouth.net> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; only 0007 version 2 of the License. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 */ 0019 #include "TestTextFunctions.h" 0020 0021 #include "TestKspreadCommon.h" 0022 0023 void TestTextFunctions::initTestCase() 0024 { 0025 FunctionModuleRegistry::instance()->loadFunctionModules(); 0026 } 0027 0028 #define CHECK_EVAL(x,y) { Value z(y); QCOMPARE(evaluate(x,z),(z)); } 0029 // CHECK_EVAL has the side effect that the value 'y' is modified, e.g due to localization 0030 // Use CHECK_VALUE2 where this this is a problem 0031 #define CHECK_EVAL2(x,y,r) { Value z(y); QCOMPARE(evaluate(x,z),r); } 0032 0033 Value TestTextFunctions::evaluate(const QString& formula, Value& ex) 0034 { 0035 Formula f; 0036 QString expr = formula; 0037 if (expr[0] != '=') 0038 expr.prepend('='); 0039 f.setExpression(expr); 0040 Value result = f.eval(); 0041 0042 if (result.isFloat() && ex.isInteger()) 0043 ex = Value(ex.asFloat()); 0044 if (result.isInteger() && ex.isFloat()) 0045 result = Value(result.asFloat()); 0046 0047 return result; 0048 } 0049 0050 void TestTextFunctions::testASC() 0051 { 0052 // TODO reactivate after function is implemented 0053 // CHECK_EVAL( "ASC(\"ABC\")", Value( "ABC" ) ); 0054 // CHECK_EVAL( "ASC(\"アイウ\")", Value( "ァィゥ" ) ); 0055 } 0056 0057 void TestTextFunctions::testCHAR() 0058 { 0059 CHECK_EVAL("CHAR(65)", Value("A")); 0060 CHECK_EVAL("CHAR(60)", Value("<")); 0061 CHECK_EVAL("CHAR(97)", Value("a")); 0062 CHECK_EVAL("CHAR(126)", Value("~")); 0063 CHECK_EVAL("CHAR(32)", Value(" ")); 0064 0065 // newline 0066 CHECK_EVAL("LEN(CHAR(10))", Value(1)); 0067 // number has to be >=0 0068 CHECK_EVAL("CHAR(-1)", Value::errorNUM()); 0069 } 0070 0071 void TestTextFunctions::testCLEAN() 0072 { 0073 CHECK_EVAL("CLEAN(\"Text\")", Value("Text")); 0074 CHECK_EVAL("CLEAN(CHAR(7)&\"Tex\"&CHAR(8)&\"t\"&CHAR(9))", Value("Text")); 0075 CHECK_EVAL("CLEAN(\"Hi there\")", Value("Hi there")); 0076 } 0077 0078 void TestTextFunctions::testCODE() 0079 { 0080 CHECK_EVAL("CODE(\"A\")", Value(65)); 0081 CHECK_EVAL("CODE(\"0\")>0", Value(true)); 0082 CHECK_EVAL("CODE(\"Text\")=CODE(\"T\")", Value(true)); 0083 } 0084 0085 void TestTextFunctions::testCONCATENATE() 0086 { 0087 CHECK_EVAL("CONCATENATE(\"Hi \"; \"there\")", Value("Hi there")); 0088 CHECK_EVAL("CONCATENATE(\"A\"; \"B\"; \"C\")", Value("ABC")); 0089 CHECK_EVAL("CONCATENATE(2;3)", Value("23")); 0090 CHECK_EVAL("CONCATENATE(23)", Value("23")); 0091 } 0092 0093 void TestTextFunctions::testEXACT() 0094 { 0095 CHECK_EVAL("EXACT(\"A\";\"A\")", Value(true)); 0096 CHECK_EVAL("EXACT(\"A\";\"a\")", Value(false)); 0097 CHECK_EVAL("EXACT(1;1)", Value(true)); 0098 CHECK_EVAL("EXACT((1/3)*3;1)", Value(true)); 0099 CHECK_EVAL("EXACT(TRUE();TRUE())", Value(true)); 0100 CHECK_EVAL("EXACT(\"1\";2)", Value(false)); 0101 CHECK_EVAL("EXACT(\"h\";1)", Value(false)); 0102 CHECK_EVAL("EXACT(\"1\";1)", Value(true)); 0103 CHECK_EVAL("EXACT(\" 1\";1)", Value(false)); 0104 } 0105 0106 void TestTextFunctions::testFIND() 0107 { 0108 CHECK_EVAL("FIND(\"b\";\"abcabc\")", Value(2)); 0109 CHECK_EVAL("FIND(\"b\";\"abcabcabc\"; 3)", Value(5)); 0110 CHECK_EVAL("FIND(\"b\";\"ABC\";1)", Value::errorVALUE()); 0111 CHECK_EVAL("FIND(\"b\";\"bbbb\")", Value(1)); 0112 CHECK_EVAL("FIND(\"b\";\"bbbb\";2)", Value(2)); 0113 CHECK_EVAL("FIND(\"b\";\"bbbb\";2.9)", Value(2)); 0114 CHECK_EVAL("FIND(\"b\";\"bbbb\";0)", Value::errorVALUE()); 0115 CHECK_EVAL("FIND(\"b\";\"bbbb\";0.9)", Value::errorVALUE()); 0116 } 0117 0118 void TestTextFunctions::testFIXED() 0119 { 0120 // localize the expected value 0121 QLocale loc = QLocale::system(); 0122 Value expected(loc.toString(12345.0, 'f', 3)); 0123 0124 CHECK_EVAL2("FIXED(12345;3)", Value("12,345.000"), expected); 0125 CHECK_EVAL("ISTEXT(FIXED(12345;3))", Value(true)); 0126 CHECK_EVAL2("FIXED(12345;3;FALSE())", Value("12,345.000"), expected); 0127 CHECK_EVAL2("FIXED(12345;3.95;FALSE())", Value("12,345.000"), expected); 0128 0129 expected = Value(loc.toString(12345.0, 'f', 4).remove(loc.groupSeparator())); 0130 CHECK_EVAL2("FIXED(12345;4;TRUE())", Value("12345.0000"), expected); 0131 expected = Value(loc.toString(123.45, 'f', 1)); 0132 CHECK_EVAL2("FIXED(123.45;1)", Value("123.5"), expected); 0133 CHECK_EVAL("FIXED(125.45; -1)", Value("130")); 0134 CHECK_EVAL("FIXED(125.45; -1.1)", Value("130")); 0135 CHECK_EVAL("FIXED(125.45; -1.9)", Value("130")); 0136 CHECK_EVAL("FIXED(125.45; -2)", Value("100")); 0137 CHECK_EVAL("FIXED(125.45; -2.87)", Value("100")); 0138 CHECK_EVAL("FIXED(125.45; -3)", Value("0")); 0139 CHECK_EVAL("FIXED(125.45; -4)", Value("0")); 0140 CHECK_EVAL("FIXED(125.45; -5)", Value("0")); 0141 } 0142 0143 void TestTextFunctions::testJIS() 0144 { 0145 // TODO reactivate after function is implemented 0146 // CHECK_EVAL( "JIS(\"ABC\")", Value( "ABC") ); 0147 // CHECK_EVAL( "JIS(\"ァィゥ\")", Value( "アイウ" ) ); 0148 } 0149 0150 void TestTextFunctions::testLEFT() 0151 { 0152 CHECK_EVAL("LEFT(\"Hello\";2)", Value("He")); 0153 CHECK_EVAL("LEFT(\"Hello\")", Value("H")); 0154 CHECK_EVAL("LEFT(\"Hello\";20)", Value("Hello")); 0155 CHECK_EVAL("LEFT(\"Hello\";0)", Value("")); 0156 CHECK_EVAL("LEFT(\"\";4)", Value("")); 0157 CHECK_EVAL("LEFT(\"xxx\";-0.1)", Value::errorVALUE()); 0158 CHECK_EVAL("LEFT(\"Hello\";2^15-1)", Value("Hello")); 0159 CHECK_EVAL("LEFT(\"Hello\";2.9)", Value("He")); 0160 } 0161 0162 void TestTextFunctions::testLEN() 0163 { 0164 CHECK_EVAL("LEN(\"Hi there\")", Value(8)); 0165 CHECK_EVAL("LEN(\"\")", Value(0)); 0166 CHECK_EVAL("LEN(55)", Value(2)); 0167 } 0168 0169 void TestTextFunctions::testLOWER() 0170 { 0171 CHECK_EVAL("LOWER(\"HELLObc7\")", Value("hellobc7")); 0172 } 0173 0174 void TestTextFunctions::testMID() 0175 { 0176 CHECK_EVAL("MID(\"123456789\";5;3)", Value("567")); 0177 CHECK_EVAL("MID(\"123456789\";20;3)", Value("")); 0178 CHECK_EVAL("MID(\"123456789\";-1;0)", Value::errorVALUE()); 0179 CHECK_EVAL("MID(\"123456789\";1;0)", Value("")); 0180 CHECK_EVAL("MID(\"123456789\";2.9;1)", Value("2")); 0181 CHECK_EVAL("MID(\"123456789\";2;2.9)", Value("23")); 0182 CHECK_EVAL("MID(\"123456789\";5)", Value("56789")); 0183 } 0184 0185 void TestTextFunctions::testNUMBERVALUE() 0186 { 0187 CHECK_EVAL( "NUMBERVALUE(\"6\"; \".\")", Value( 6 ) ); // VALUE converts text to numbers (unlike N). 0188 CHECK_EVAL( "NUMBERVALUE(\"6,000.5\"; \".\")", Value( 6000.5 ) ); // Period works. 0189 CHECK_EVAL( "NUMBERVALUE(\"6.000,5\"; \",\")", Value( 6000.5 ) ); // Comma works 0190 CHECK_EVAL( "NUMBERVALUE(\"3!456!000*567\"; \"*\"; \"!\")", Value( 3456000.567 ) ); // Thousands separator works 0191 CHECK_EVAL( "NUMBERVALUE(\"+6,000.5\"; \".\")", Value( 6000.5 ) ); // Positive sign 0192 CHECK_EVAL( "NUMBERVALUE(\"-6,000.5\"; \".\")", Value( -6000.5 ) ); // Negative sign 0193 } 0194 0195 void TestTextFunctions::testPROPER() 0196 { 0197 CHECK_EVAL("PROPER(\"hello there\")", Value("Hello There")); 0198 CHECK_EVAL("PROPER(\"HELLO THERE\")", Value("Hello There")); 0199 CHECK_EVAL("PROPER(\"HELLO.THERE\")", Value("Hello.There")); 0200 } 0201 0202 void TestTextFunctions::testREPLACE() 0203 { 0204 CHECK_EVAL("REPLACE(\"123456789\";5;3;\"Q\")", Value("1234Q89")); 0205 CHECK_EVAL("REPLACE(\"123456789\";5;0;\"Q\")", Value("1234Q56789")); 0206 } 0207 0208 void TestTextFunctions::testREPT() 0209 { 0210 CHECK_EVAL("REPT(\"X\";3)", Value("XXX")); 0211 CHECK_EVAL("REPT(\"XY\";2)", Value("XYXY")); 0212 CHECK_EVAL("REPT(\"X\";2.9)", Value("XX")); 0213 CHECK_EVAL("REPT(\"XY\";2.9)", Value("XYXY")); 0214 CHECK_EVAL("REPT(\"X\";0)", Value("")); 0215 CHECK_EVAL("REPT(\"XYZ\";0)", Value("")); 0216 CHECK_EVAL("REPT(\"X\";-1)", Value::errorVALUE()); 0217 CHECK_EVAL("REPT(\"XYZ\";-0.1)", Value::errorVALUE()); 0218 } 0219 0220 void TestTextFunctions::testRIGHT() 0221 { 0222 CHECK_EVAL("RIGHT(\"Hello\";2)", Value("lo")); 0223 CHECK_EVAL("RIGHT(\"Hello\")", Value("o")); 0224 CHECK_EVAL("RIGHT(\"Hello\";20)", Value("Hello")); 0225 CHECK_EVAL("RIGHT(\"Hello\";0)", Value("")); 0226 CHECK_EVAL("RIGHT(\"\";4)", Value("")); 0227 CHECK_EVAL("RIGHT(\"xxx\";-1)", Value::errorVALUE()); 0228 CHECK_EVAL("RIGHT(\"xxx\";-0.1)", Value::errorVALUE()); 0229 CHECK_EVAL("RIGHT(\"Hello\";2^15-1)", Value("Hello")); 0230 CHECK_EVAL("RIGHT(\"Hello\";2.9)", Value("lo")); 0231 } 0232 0233 void TestTextFunctions::testSEARCH() 0234 { 0235 CHECK_EVAL("=SEARCH(\"b\";\"abcabc\")", Value(2)); 0236 CHECK_EVAL("=SEARCH(\"b\";\"abcabcabc\"; 3)", Value(5)); 0237 CHECK_EVAL("=SEARCH(\"b\";\"ABC\";1)", Value(2)); 0238 CHECK_EVAL("=SEARCH(\"c?a\";\"abcabcda\")", Value(6)); 0239 CHECK_EVAL("=SEARCH(\"e*o\";\"yes and no\")", Value(2)); 0240 CHECK_EVAL("=SEARCH(\"b*c\";\"abcabcabc\")", Value(2)); 0241 } 0242 0243 void TestTextFunctions::testSUBSTITUTE() 0244 { 0245 CHECK_EVAL("SUBSTITUTE(\"121212\";\"2\";\"ab\")", Value("1ab1ab1ab")); 0246 CHECK_EVAL("SUBSTITUTE(\"121212\";\"2\";\"ab\";2)", Value("121ab12")); 0247 CHECK_EVAL("SUBSTITUTE(\"Hello\";\"x\";\"ab\")", Value("Hello")); 0248 CHECK_EVAL("SUBSTITUTE(\"xyz\";\"\";\"ab\")", Value("xyz")); 0249 CHECK_EVAL("SUBSTITUTE(\"\";\"\";\"ab\")", Value("")); 0250 CHECK_EVAL("SUBSTITUTE(\"Hello\"; \"H\"; \"J\"; 0)", Value::errorVALUE()); 0251 CHECK_EVAL("SUBSTITUTE(\"Hello\"; \"H\"; \"J\"; 1)", Value("Jello")); 0252 CHECK_EVAL("SUBSTITUTE(\"fo\"\"o\";\"o\";\"a\")", Value("fa\"a")); 0253 } 0254 0255 void TestTextFunctions::testT() 0256 { 0257 CHECK_EVAL("T(\"Hi\")", Value("Hi")); 0258 CHECK_EVAL("T(5)", Value("")); 0259 } 0260 0261 void TestTextFunctions::testTRIM() 0262 { 0263 CHECK_EVAL("TRIM(\" Hi \")", Value("Hi")); 0264 CHECK_EVAL("LEN(TRIM(\"H\" & \" \" & \" \" & \"I\"))", Value(3)); 0265 } 0266 0267 void TestTextFunctions::testUNICHAR() 0268 { 0269 CHECK_EVAL("UNICHAR(65)", Value("A")); 0270 CHECK_EVAL("UNICHAR(8364)", Value(QChar(8364))); 0271 } 0272 0273 void TestTextFunctions::testUNICODE() 0274 { 0275 QChar euro(8364); 0276 0277 CHECK_EVAL("UNICODE(\"A\")", Value(65)); 0278 CHECK_EVAL("UNICODE(\"AB€C\")", Value(65)); 0279 CHECK_EVAL(QString("UNICODE(\"%1\")").arg(euro), Value(8364)); 0280 CHECK_EVAL(QString("UNICODE(\"%1F\")").arg(euro), Value(8364)); 0281 } 0282 0283 void TestTextFunctions::testUPPER() 0284 { 0285 CHECK_EVAL("UPPER(\"Habc7\")", Value("HABC7")); 0286 } 0287 0288 void TestTextFunctions::testROT13() 0289 { 0290 CHECK_EVAL("ROT13(\"KSpread\")", Value("XFcernq")); 0291 CHECK_EVAL("ROT13(\"XFcernq\")", Value("KSpread")); 0292 CHECK_EVAL("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETROT13(\"KSpread\")", Value("XFcernq")); 0293 CHECK_EVAL("COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETROT13(\"XFcernq\")", Value("KSpread")); 0294 } 0295 0296 void TestTextFunctions::testBAHTTEXT() 0297 { 0298 Value r; 0299 r = evaluate("BAHTTEXT(23)", r); 0300 CHECK_EVAL("BAHTTEXT(23)", r); 0301 CHECK_EVAL("COM.MICROSOFT.BAHTTEXT(23)", r); 0302 } 0303 0304 void TestTextFunctions::testTEXT() 0305 { 0306 CHECK_EVAL("TEXT(TIME(13;10;43);\"hh:mm\")", Value("13:10")); 0307 } 0308 0309 QTEST_MAIN(TestTextFunctions)