• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

test/TestXPathLex.cpp

00001 /*
00002  *   This file is part of the Standard Portable Library (SPL).
00003  *
00004  *   SPL is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   SPL is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with SPL.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 #include <spl/Debug.h>
00018 #include <spl/Log.h>
00019 #include <spl/xml/xpath/private/XPathLex.h>
00020 
00021 #ifdef DEBUG
00022 
00023 const char* const _theNumericTestInput[] =
00024 {
00025     "9 + 7 - 6 * 42 + 36 div 3 + 100 - 2 * 6",
00026     "9 + 7 - 6 + 3 + 24 - 32 - 89 + 123 - 12256 + 89957",
00027     "0 + 0",
00028     "1 div 2",
00029     "1 * 0.25",
00030     "3 * 3 * 3",
00031     "9 div 3 div 3",
00032     "15.95 - 13.56",
00033     0
00034 };
00035 
00036 const double _theNumericTestExpectedOutput[] =
00037 {
00038     -136.0,
00039     77740.0,
00040     0,
00041     0.5,
00042     0.25,
00043     27,
00044     1,
00045     15.95 - 13.56,
00046     0   // This is a dummy entry and should be last.
00047 };
00048 
00049 const char* const   _theBooleanTestInput[] =
00050 {
00051     "0 < 2 < 3",
00052     "0 < 2 > 3",
00053     "1 < 2 < 3",
00054 
00055     "0 div 0 != 0 div 0",
00056     "0 div 0 = 0 div 0",
00057     "1 < 0 div 0",
00058     "1 <= 0 div 0",
00059     "2 > 0 div 0",
00060     "2 >= 0 div 0",
00061 
00062     "1 < 2",
00063     "1500 < 657",
00064     "1465787676 < 5 div 0",
00065     "4657 div 0 < 4563745658",
00066 
00067     "1000 <= 256000",
00068     "1000 <= 1000",
00069     "200564 <= 1999",
00070     "5768594 <= 56 div 0",
00071     "564783 div 0 <= 6758494857",
00072 
00073     "2015 > 100",
00074     "56478 > 240000",
00075     "4657 div 0 > 57683946",
00076     "573068574 > 5 div 0",
00077 
00078     "46000 >= 1500",
00079     "56983 >= 56983",
00080     "460983 >= 1500000",
00081     "67594876 div 0 >= 576849",
00082 
00083     "1465787676 >= 5 div 0",
00084     "-1465787676 >= -5 div 0",
00085     "-1679 < -87 div 0",
00086 
00087     "1 = 2 = 0",
00088     "1 = 2 != 0",
00089 
00090     0
00091 };
00092 
00093 const bool  _theBooleanTestExpectedOutput[] =
00094 {
00095     true,
00096     false,
00097     true,
00098 
00099     true,
00100     false,
00101     false,
00102     false,
00103     false,
00104     false,
00105 
00106     true,
00107     false,
00108     true,
00109     false,
00110 
00111     true,
00112     true,
00113     false,
00114     true,
00115     false,
00116 
00117     true,
00118     false,
00119     true,
00120     false,
00121 
00122     true,
00123     true,
00124     false,
00125     true,
00126 
00127     false,
00128     true,
00129     false,
00130 
00131     true,
00132     false,
00133 
00134     0
00135 };
00136 
00137 const char* const   _theStringTestInput[] =
00138 {
00139     "string(0)",
00140     "string(1.5)",
00141     "string(-1.5)",
00142     "string(0.5)",
00143     "string(-0.5)",
00144     "string(9)",
00145     "string(-9)",
00146     "string(\"9\")",
00147     "string(0.25)",
00148 
00149     "concat(\"foo\", \"bar\")",
00150     "concat(\"foo\", \"bar\", \"sky\")",
00151 
00152     "contains(\"foobar\", \"oba\")",
00153     "contains(\"LotusXSL4C is great\", \"boag\")",
00154 
00155     "starts-with(\"foobar\", \"foo\")",
00156     "starts-with(\"LotusXSL4C is great\", \"boag\")",
00157 
00158     "substring-after(\"1999/04/01\", \"/\")",
00159     "substring-after(\"1999/04/01\", \"19\")",
00160 
00161     "substring-before(\"1999/04/01\", \"/\")",
00162     "substring-before(\"1999/04/01\", \"01\")",
00163 
00164     "substring(\"12345\", 1.5, 2.6)",
00165     "substring(\"12345\", 0, 3)",
00166     "substring(\"12345\", 5, 29)",
00167     "substring(\"12345\", -1, 2)",
00168     "substring(\"12345\", -2, -1)",
00169     "substring(\"12345\", -2)",
00170 
00171     "normalize-space(\"   aa   a  \")",
00172 
00173     "translate(\"---aaa--\", \"abc-\", \"ABC\")",
00174 
00175     "5 = 0",
00176     "5 = 5",
00177     0
00178 };
00179 
00180 const char* const   _theStringTestExpectedOutput[] =
00181 {
00182     "0",
00183     "1.5",
00184     "-1.5",
00185     "0.5",
00186     "-0.5",
00187     "9",
00188     "-9",
00189     "9",
00190     "0.25",
00191 
00192     "foobar",
00193     "foobarsky",
00194 
00195     "true",
00196     "false",
00197 
00198     "true",
00199     "false",
00200 
00201     "04/01",
00202     "99/04/01",
00203 
00204     "1999",
00205     "1999/04/",
00206 
00207     "234",
00208     "12",
00209     "5",
00210     "",
00211     "",
00212     "12345",
00213 
00214     "aa a",
00215 
00216     "AAA",
00217 
00218     "false",
00219     "true",
00220     0
00221 };
00222 
00223 static void _TestXPathLexNumeric()
00224 {
00225         XPathLex lex;
00226 
00227         // "9 + 7 - 6 * 42 + 36 div 3 + 100 - 2 * 6",
00228         lex.Tokenize(_theNumericTestInput[0]);
00229 
00230         DEBUG_CLEAR_MEM_CHECK_POINTS();
00231         lex.CheckMem();
00232         UNIT_ASSERT_MEM_NOTED("_TestXPathLexNumeric");
00233 
00234         UNIT_ASSERT("9", lex.CurrentLexum() == "9");
00235         UNIT_ASSERT("9", lex.CurrentToken() == XPathLex::XP_INT);
00236         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00237 
00238         UNIT_ASSERT("+", lex.Match(XPathLex::XP_INT) == XPathLex::XP_PLUS);
00239         UNIT_ASSERT("+", lex.CurrentLexum() == "+");
00240         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00241 
00242         UNIT_ASSERT("7", lex.Match(XPathLex::XP_PLUS) == XPathLex::XP_INT);
00243         UNIT_ASSERT("7", lex.CurrentLexum() == "7");
00244         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00245 
00246         UNIT_ASSERT("-", lex.Match(XPathLex::XP_INT) == XPathLex::XP_MIN);
00247         UNIT_ASSERT("-", lex.CurrentLexum() == "-");
00248         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00249 
00250         UNIT_ASSERT("6", lex.Match(XPathLex::XP_MIN) == XPathLex::XP_INT);
00251         UNIT_ASSERT("6", lex.CurrentLexum() == "6");
00252         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00253 
00254         UNIT_ASSERT("*", lex.Match(XPathLex::XP_INT) == XPathLex::XP_STAR);
00255         UNIT_ASSERT("*", lex.CurrentLexum() == "*");
00256         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00257 
00258         UNIT_ASSERT("42", lex.Match(XPathLex::XP_STAR) == XPathLex::XP_INT);
00259         UNIT_ASSERT("42", lex.CurrentLexum() == "42");
00260         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00261 
00262         UNIT_ASSERT("+", lex.Match(XPathLex::XP_INT) == XPathLex::XP_PLUS);
00263         UNIT_ASSERT("+", lex.CurrentLexum() == "+");
00264         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00265 
00266         UNIT_ASSERT("36", lex.Match(XPathLex::XP_PLUS) == XPathLex::XP_INT);
00267         UNIT_ASSERT("36", lex.CurrentLexum() == "36");
00268         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00269 
00270         UNIT_ASSERT("div", lex.Match(XPathLex::XP_INT) == XPathLex::XP_LITERAL);
00271         UNIT_ASSERT("div", lex.CurrentLexum() == "div");
00272         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00273 
00274         UNIT_ASSERT("3", lex.Match(XPathLex::XP_LITERAL) == XPathLex::XP_INT);
00275         UNIT_ASSERT("3", lex.CurrentLexum() == "3");
00276         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00277 
00278         UNIT_ASSERT("+", lex.Match(XPathLex::XP_INT) == XPathLex::XP_PLUS);
00279         UNIT_ASSERT("+", lex.CurrentLexum() == "+");
00280         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00281 
00282         UNIT_ASSERT("100", lex.Match(XPathLex::XP_PLUS) == XPathLex::XP_INT);
00283         UNIT_ASSERT("100", lex.CurrentLexum() == "100");
00284         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00285 
00286         UNIT_ASSERT("-", lex.Match(XPathLex::XP_INT) == XPathLex::XP_MIN);
00287         UNIT_ASSERT("-", lex.CurrentLexum() == "-");
00288         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00289 
00290         UNIT_ASSERT("2", lex.Match(XPathLex::XP_MIN) == XPathLex::XP_INT);
00291         UNIT_ASSERT("2", lex.CurrentLexum() == "2");
00292         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00293 
00294         UNIT_ASSERT("*", lex.Match(XPathLex::XP_INT) == XPathLex::XP_STAR);
00295         UNIT_ASSERT("*", lex.CurrentLexum() == "*");
00296         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00297 
00298         UNIT_ASSERT("6", lex.Match(XPathLex::XP_STAR) == XPathLex::XP_INT);
00299         UNIT_ASSERT("6", lex.CurrentLexum() == "6");
00300         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00301 
00302         UNIT_ASSERT("EOF", lex.Match(XPathLex::XP_INT) == XPathLex::XP_EOF);
00303         UNIT_ASSERT("EOF", lex.CurrentToken() == XPathLex::XP_EOF);
00304         UNIT_ASSERT("EOF LEX", lex.CurrentLexum() == "");
00305         UNIT_ASSERT("HasMoreTokens", !lex.HasMoreTokens());
00306 
00307         Log::SWriteOkFail( "XPathLex numerics 1" );
00308 }
00309 
00310 static void _TestXPathLexNumeric2()
00311 {
00312         XPathLex lex;
00313 
00314         // "15.95 - 13.56",
00315         lex.Tokenize(_theNumericTestInput[7]);
00316         UNIT_ASSERT("15.95", lex.CurrentLexum() == "15.95");
00317         UNIT_ASSERT("15.95", lex.CurrentToken() == XPathLex::XP_FLOAT);
00318         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00319 
00320         UNIT_ASSERT("-", lex.Match(XPathLex::XP_FLOAT) == XPathLex::XP_MIN);
00321         UNIT_ASSERT("-", lex.CurrentLexum() == "-");
00322         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00323 
00324         UNIT_ASSERT("13.56", lex.Match(XPathLex::XP_MIN) == XPathLex::XP_FLOAT);
00325         UNIT_ASSERT("13.56", lex.CurrentLexum() == "13.56");
00326         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00327 
00328         UNIT_ASSERT("EOF", lex.Match(XPathLex::XP_FLOAT) == XPathLex::XP_EOF);
00329         UNIT_ASSERT("EOF", lex.CurrentToken() == XPathLex::XP_EOF);
00330         UNIT_ASSERT("EOF LEX", lex.CurrentLexum() == "");
00331         UNIT_ASSERT("HasMoreTokens", !lex.HasMoreTokens());
00332 
00333         Log::SWriteOkFail( "XPathLex numerics 2" );
00334 }
00335 
00336 static void _TestXPathLexOperators()
00337 {
00338         XPathLex lex;
00339 
00340         lex.Tokenize("-12 < .12 <= -1.0 == 1 != 1 > 2 >= 3");
00341 
00342         UNIT_ASSERT("-12", lex.CurrentLexum() == "-12");
00343         UNIT_ASSERT("15.95", lex.CurrentToken() == XPathLex::XP_INT);
00344         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00345 
00346         UNIT_ASSERT("<", lex.Match(XPathLex::XP_INT) == XPathLex::XP_LT);
00347         UNIT_ASSERT("<", lex.CurrentLexum() == "<");
00348         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00349 
00350         UNIT_ASSERT(".12", lex.Match(XPathLex::XP_LT) == XPathLex::XP_FLOAT);
00351         UNIT_ASSERT(".12", lex.CurrentLexum() == ".12");
00352         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00353 
00354         UNIT_ASSERT("<=", lex.Match(XPathLex::XP_FLOAT) == XPathLex::XP_LTEQ);
00355         UNIT_ASSERT("<=", lex.CurrentLexum() == "<=");
00356         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00357 
00358         UNIT_ASSERT("-1.0", lex.Match(XPathLex::XP_LTEQ) == XPathLex::XP_FLOAT);
00359         UNIT_ASSERT("-1.0", lex.CurrentLexum() == "-1.0");
00360         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00361 
00362         UNIT_ASSERT("==", lex.Match(XPathLex::XP_FLOAT) == XPathLex::XP_EQEQ);
00363         UNIT_ASSERT("==", lex.CurrentLexum() == "==");
00364         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00365 
00366         UNIT_ASSERT("1", lex.Match(XPathLex::XP_EQEQ) == XPathLex::XP_INT);
00367         UNIT_ASSERT("1", lex.CurrentLexum() == "1");
00368         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00369 
00370         UNIT_ASSERT("!=", lex.Match(XPathLex::XP_INT) == XPathLex::XP_NEQ);
00371         UNIT_ASSERT("!=", lex.CurrentLexum() == "!=");
00372         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00373 
00374         UNIT_ASSERT("1", lex.Match(XPathLex::XP_NEQ) == XPathLex::XP_INT);
00375         UNIT_ASSERT("1", lex.CurrentLexum() == "1");
00376         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00377 
00378         UNIT_ASSERT(">", lex.Match(XPathLex::XP_INT) == XPathLex::XP_GT);
00379         UNIT_ASSERT(">", lex.CurrentLexum() == ">");
00380         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00381 
00382         UNIT_ASSERT("2", lex.Match(XPathLex::XP_GT) == XPathLex::XP_INT);
00383         UNIT_ASSERT("2", lex.CurrentLexum() == "2");
00384         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00385 
00386         UNIT_ASSERT(">=", lex.Match(XPathLex::XP_INT) == XPathLex::XP_GTEQ);
00387         UNIT_ASSERT(">=", lex.CurrentLexum() == ">=");
00388         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00389 
00390         UNIT_ASSERT("3", lex.Match(XPathLex::XP_GTEQ) == XPathLex::XP_INT);
00391         UNIT_ASSERT("3", lex.CurrentLexum() == "3");
00392         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00393 
00394         UNIT_ASSERT("EOF", lex.Match(XPathLex::XP_INT) == XPathLex::XP_EOF);
00395         UNIT_ASSERT("EOF", lex.CurrentToken() == XPathLex::XP_EOF);
00396         UNIT_ASSERT("EOF LEX", lex.CurrentLexum() == "");
00397         UNIT_ASSERT("HasMoreTokens", !lex.HasMoreTokens());
00398 
00399         Log::SWriteOkFail( "XPathLex operators" );
00400 }
00401 
00402 static void _TestXPathLexExpr()
00403 {
00404         XPathLex lex;
00405 
00406         lex.Tokenize("//title[@lang='eng']");
00407 
00408         UNIT_ASSERT("//", lex.CurrentLexum() == "//");
00409         UNIT_ASSERT("15.95", lex.CurrentToken() == XPathLex::XP_SLASHSLASH);
00410         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00411 
00412         UNIT_ASSERT("title", lex.Match(XPathLex::XP_SLASHSLASH) == XPathLex::XP_LITERAL);
00413         UNIT_ASSERT("title", lex.CurrentLexum() == "title");
00414         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00415 
00416         UNIT_ASSERT("[", lex.Match(XPathLex::XP_LITERAL) == XPathLex::XP_LBRAC);
00417         UNIT_ASSERT("[", lex.CurrentLexum() == "[");
00418         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00419 
00420         UNIT_ASSERT("@", lex.Match(XPathLex::XP_LBRAC) == XPathLex::XP_AT);
00421         UNIT_ASSERT("@", lex.CurrentLexum() == "@");
00422         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00423 
00424         UNIT_ASSERT("lang", lex.Match(XPathLex::XP_AT) == XPathLex::XP_LITERAL);
00425         UNIT_ASSERT("lang", lex.CurrentLexum() == "lang");
00426         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00427 
00428         UNIT_ASSERT("=", lex.Match(XPathLex::XP_LITERAL) == XPathLex::XP_EQ);
00429         UNIT_ASSERT("=", lex.CurrentLexum() == "=");
00430         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00431 
00432         UNIT_ASSERT("eng", lex.Match(XPathLex::XP_EQ) == XPathLex::XP_STRING);
00433         UNIT_ASSERT("eng", lex.CurrentLexum() == "eng");
00434         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00435 
00436         UNIT_ASSERT("]", lex.Match(XPathLex::XP_STRING) == XPathLex::XP_RBRAC);
00437         UNIT_ASSERT("]", lex.CurrentLexum() == "]");
00438         UNIT_ASSERT("HasMoreTokens", lex.HasMoreTokens());
00439 
00440         UNIT_ASSERT("EOF", lex.Match(XPathLex::XP_RBRAC) == XPathLex::XP_EOF);
00441         UNIT_ASSERT("EOF", lex.CurrentToken() == XPathLex::XP_EOF);
00442         UNIT_ASSERT("EOF LEX", lex.CurrentLexum() == "");
00443         UNIT_ASSERT("HasMoreTokens", !lex.HasMoreTokens());
00444 
00445         Log::SWriteOkFail( "XPathLex expressions" );
00446 }
00447 
00448 void _TestXPathLex()
00449 {
00450         _TestXPathLexNumeric();
00451         DEBUG_CLEAR_MEM_CHECK_POINTS();
00452         DEBUG_DUMP_MEM_LEAKS();
00453 
00454         _TestXPathLexNumeric2();
00455         DEBUG_CLEAR_MEM_CHECK_POINTS();
00456         DEBUG_DUMP_MEM_LEAKS();
00457 
00458         _TestXPathLexOperators();
00459         DEBUG_CLEAR_MEM_CHECK_POINTS();
00460         DEBUG_DUMP_MEM_LEAKS();
00461 
00462         _TestXPathLexExpr();
00463         DEBUG_CLEAR_MEM_CHECK_POINTS();
00464         DEBUG_DUMP_MEM_LEAKS();
00465 }
00466 
00467 #endif
00468 
00469 
00470