// -*- c++ -*- /* * Jakelib2 - General purpose C++ library * Copyright (C) 2001 Florian Wolff (florian@donuz.de) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: Test.jlc,v 1.128 2003/09/28 12:34:31 florian Exp $ */ #include "Test.h" #include #include #include #include #include // ---------------------------------------------------------------------------- // List prototypes for all test procedure here: void booleanTest(); void localeTest(); void encodingTest(); void fileTest(); void stackTraceTest(); void vectorTest(); void calendarTest(); void stringTest(); void printfTest(); void classTest(); void processTest(); void numberTest(); void numberFormatTest(); void fileFilterTest(); void arrayListTest(); void hashTest(); void floatTest(); void dateFormatTest(); void timeZoneTest(); void systemTest(); void regexTest(); // List names, titles and function pointers for all test procedures here: static TEST_INFO tests[] = { {"string", "String, StringBuffer", stringTest}, {"file", "File", fileTest}, {"encoding", "Character Encodings", encodingTest}, {"vector", "Vector", vectorTest}, {"hash", "Hashtable", hashTest}, {"boolean", "Boolean", booleanTest}, {"arraylist", "ArrayList", arrayListTest}, {"class", "Class, RTTI", classTest}, {"process", "Process", processTest}, {"number", "Integer, Long", numberTest}, // {"float", "Float, Double", floatTest}, {"numberformat", "DecimalFormat, NumberFormat", numberFormatTest}, {"filefilter", "WildcardFilter", fileFilterTest}, {"locale", "Locale", localeTest}, {"calendar", "Calendar, GregorianCalendar", calendarTest}, {"printf", "printf() method", printfTest}, {"dateformat", "SimpleDateFormat", dateFormatTest}, {"timezone", "TimeZone, SimpleTimeZone", timeZoneTest}, {"regex", "Pattern, Matcher", regexTest}, {"system", "System, Runtime", systemTest}, null }; // ---------------------------------------------------------------------------- using namespace jakelib::util; using namespace jakelib::io; using namespace jakelib::text; Commandline* params; int passedTests = 0; int failedTests = 0; jlong startTime; void start(String *name) { System::out->println(`"\n===== "`->plus(name) ->plus(`" ===================================\n"`)); } void start(char *name) { System::out->println(`"\n===== "` .. name .. `" ===================================\n"`); } void dumpObjectCounter() { #ifdef JAKELIB_DEBUG static int subtract = 0; int created = Object::getNewCounter(); int deleted = Object::getDeleteCounter(); int left = created - deleted; System::out->println(`"Objects: allocated: "`->plus((jlong) created) ->plus(`"; deleted: "`)->plus((jlong) deleted) ->plus(`"; left: "`)->plus((jlong) left) ->plus(`"; diff: "`)->plus((jlong) (left - subtract))); if (subtract == 0) subtract = created; #endif } void gc() { System::out->print(`"[Invoking Garbage Collector..."`); fflush(stdout); // GC_gcollect(); Runtime::getRuntime()->gc(); /* System::out->println(String("GC_get_heap_size=") + GC_get_heap_size()); System::out->println(String("GC_get_free_bytes=") + GC_get_free_bytes()); System::out->println(String("GC_get_total_bytes=") + GC_get_total_bytes());*/ System::out->println(`"done.]"`); } void jtest_message(String* info) { System::out->printf(`"%-72S"`, info->substring(0, 72)); } void jtest_passed(String* info) { jtest_message(info); System::out->println(`"ok"`); } void jtest_failed_wrong_exception(String* info, char* expr, Throwable *ex, char* exceptName) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->println(`" [exception thrown was: "` .. ex->getClass()->getName() .. `"\n but should be: "` .. exceptName); } void jtest_failed_wrong_exception(String* info, char* expr, char* exceptName) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->println(`" [exception thrown was: "` .. `"\n but should be: "` .. exceptName); } void jtest_failed_no_exception(String* info, char* expr, char* exceptName) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->println(`" [exception "` .. exceptName .. `" should be thrown]"`); } void jtest_failed_wrong_return(String* info, String *val, String *expVal) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->printf(`" [return value was\n '%S'\n but should be\n '%S']\n"`, val, expVal); } void jtest_failed_wrong_return(String* info, int val, int expVal) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->printf(`" [return value was '%i' but should be '%i']\n"`, val, expVal); } void jtest_failed_wrong_return(String* info, jboolean val, jboolean expVal) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->printf(`" [return value was '%S' but should be '%S']\n"`, Boolean::toString(val), Boolean::toString(expVal)); } void jtest_failed_exception(String* info, Throwable *ex) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->printf(`" [exception thrown was: "` .. ex->getClass()->getName() .. `"]\n"`); } void jtest_failed_exception(String* info) { jtest_message(info); System::out->println(`"FAILED!"`); System::out->printf(`" [exception thrown was: ]\n"`); } void jtest_summary() { System::out->println(); System::out->println(); System::out->println(`" T E S T S U M M A R Y"`); System::out->println(`"-------------------------------------------------------------------------------"`); if (failedTests > 0) { System::out->printf(`"!!!! %3i of %3i tests failed. !!!!\n"`, failedTests, failedTests + passedTests); } else { System::out->printf(`" All %i tests passed.\n"`, passedTests); System::out->printf(`" Time elapsed: %l millis\n"`, System::currentTimeMillis()-startTime); } System::out->println(`"-------------------------------------------------------------------------------"`); System::out->println(); } void printfTest() { try { jchar ch = '@'; jdouble d = 56.7899; System::out->printf(`"%%Hello, >%-10S<: %2i.%02i.%05i %5d - %c, '%10s'!\n"`, `"world"`, 1, 1, 2003, d, ch, "foo"); System::out->printf(`">>%-5i<< >>%5i<< >>%05i<<\n"`, 98, 98, 98, 98); System::out->printf(`">>%-5i<< >>%5i<< >>%05i<<\n"`, -98, -98, -98, -98); System::out->printf(`">>%-5i<< >>%5i<< >>%05i<<\n"`, 1234598, 1234598, 1234598, 1234598); System::out->printf(`">>%-5i<< >>%5i<< >>%05i<<\n"`, -1234598, -1234598, -1234598, -1234598); System::out->printf(`"This is null: '%S'\n"`, (String*) null); } catch (Exception *ex) { System::out->println(ex); } } void numberFormatTest() { NumberFormat* nf = NumberFormat::getInstance(); nf = new DecimalFormat(`"#,##0.###"`); System::out->println(`"1 -> '"` .. nf->format((jlong) 1) .. `"'"`); System::out->println(`"12 -> '"` .. nf->format((jlong) 12) .. `"'"`); System::out->println(`"123 -> '"` .. nf->format((jlong) 123) .. `"'"`); System::out->println(`"1234 -> '"` .. nf->format((jlong) 1234) .. `"'"`); System::out->println(`"12345 -> '"` .. nf->format((jlong) 12345) .. `"'"`); System::out->println(`"123456 -> '"` .. nf->format((jlong) 123456) .. `"'"`); System::out->println(`"1234567 -> '"` .. nf->format((jlong) 1234567) .. `"'"`); System::out->println(`"-1234 -> '"` .. nf->format((jlong) -1234) .. `"'"`); System::out->println(`"-12345.678 -> '"` .. nf->format((jfloat) -12345.678) .. `"'"`); System::out->println(`"System::currentTimeMillis() -> '"` .. nf->format(System::currentTimeMillis()) .. `"'"`); } void checkInstanceOf(Object* obj, char* var, String* name) { System::out->println(`""` .. var .. `"->instanceOf(\""` .. name .. `"\") = "` .. new Boolean(obj->instanceOf(name))); } void printSuperClass(Object* obj, char* var) { System::out->println(String().plus(var)->plus(":")); Class* c = obj->getClass(); do { System::out->println(`" -> "`->plus(c->getName())); c = c->getSuperclass(); } while (c != null); } void printInterfaces(Object* obj) { Class* c = obj->getClass(); do { Classs* interfaces = c->getInterfaces(); System::out->println(c->getName() .. `" implements:"`); for (int idx = 0; idx < interfaces->length(); idx++) { System::out->println(`" - "` .. interfaces->get(idx)); } c = c->getSuperclass(); } while (c != null); } void classTest() { Long* l = new Long(3478489); String* s = new String("This is just a short one"); List *list = new ArrayList(); ArrayListIterator *it = new ArrayListIterator(null); ArrayList* arrayList = new ArrayList(); Strings *strArr = new Strings(10); jints *jintArr = new jints(10); checkInstanceOf(l, "long", `"jakelib.lang.Long"`); checkInstanceOf(l, "long", `"jakelib.lang.Number"`); checkInstanceOf(l, "long", `"jakelib.lang.Object"`); checkInstanceOf(l, "long", `"jakelib.lang.String"`); checkInstanceOf(s, "string", `"jakelib.lang.Object"`); checkInstanceOf(s, "string", `"jakelib.lang.String"`); checkInstanceOf(s, "string", `"jakelib.lang.Number"`); checkInstanceOf(it, "arrayListIterator", `"jakelib.util.Iterator"`); checkInstanceOf(it, "arrayListIterator", `"jakelib.util.ArrayListIterator"`); checkInstanceOf(arrayList, "arrayList", `"jakelib.util.Map"`); checkInstanceOf(arrayList, "arrayList", `"jakelib.util.List"`); checkInstanceOf(strArr, "strArr", `"jakelib.lang.Object"`); checkInstanceOf(strArr, "strArr", `"jakelib.lang.String"`); checkInstanceOf(strArr, "strArr", `"jakelib.lang.String[]"`); Stack* stack = new Stack(); Byte* byte = new Byte(11); Integer* integer = new Integer(19783); printSuperClass(l, "long"); printSuperClass(s, "string"); printSuperClass(arrayList, "arrayList"); printSuperClass(stack, "stack"); printSuperClass(byte, "byte"); printSuperClass(integer, "integer"); printSuperClass(it, "arrayListIterator"); printSuperClass(strArr, "strArr"); printSuperClass(jintArr, "jintArr"); printInterfaces(l); printInterfaces(s); printInterfaces(it); printInterfaces((AbstractCollection*) arrayList); } void tryParseInt(String* s, int radix) { System::out->print(`"Integer::parseInt(\""`->plus(s != null ? s : `""`) ->plus(`"\", "`)->plus((jlong) radix)->plus(`") "`)); try { System::out->println(String().plus((jlong) Integer::parseInt(s, radix))); } catch (Exception *ex) { System::out->println(`"--> "`->plus(ex)); } } void numberTest() { const int radix[] = {2, 10, 16, -1}; const int integers[] = {0x7fffffff, 0, 0x80000000, -1}; for (int r = 0;; r++) { if (radix[r] == -1) break; for (int i = 0;; i++) { if (integers[i] == -1) break; System::out->println(`"Integer::toString("` ->plus((jlong) integers[i])->plus(`", "`) ->plus((jlong) radix[r])->plus(`") = '"`) ->plus(Integer::toString(integers[i], radix[r]))->plus(`"'"`)); } } tryParseInt(`"1234r"`, 10); tryParseInt(null, 10); tryParseInt(`"31415"`, 10); tryParseInt(`"-0000110111"`, 2); tryParseInt(`"-2147483648"`, 10); tryParseInt(`"765"`, 38); System::out->println(`"Integer::toHexString(65535) = "`->plus(Integer::toHexString(65535))); // System::out->println(String("Integer::toHexString(-345) = ").plus(Integer::toHexString(-345))); System::out->println(`"Integer::toHexString(65535) = "`->plus(Integer::toBinaryString(65535))); //System::out->println(String("Integer::decode(\"0xf0f0f0\") = ") + Integer::decode("0xf0f0f0").toString().getChars()); System::out->println(`"Long::MAX_VALUE = "`->plus((jlong) Long::MAX_VALUE)); System::out->println(`"Long::MIN_VALUE = "`->plus((jlong) Long::MIN_VALUE)); System::out->println(`"Integer::MAX_VALUE = "`->plus((jlong) Integer::MAX_VALUE)); System::out->println(`"Integer::MIN_VALUE = "`->plus((jlong) Integer::MIN_VALUE)); } void tryParseDouble(String* s) { System::out->print(`"Double::parseDouble(\""`->plus(s != null ? s : `""`) ->plus(`"\") "`)); try { System::out->println(String().plus(Double::parseDouble(s))); } catch (Exception *ex) { System::out->println(`"--> "`->plus(ex)); } } void doublelongTest(jdouble dbl) { jlong lngret = Double::doubleToLongBits(dbl); jdouble dblret = Double::longBitsToDouble(lngret); jlong lngrawret = Double::doubleToRawLongBits(dbl); jdouble dblrawret = Double::longBitsToDouble(lngrawret); System::out->println(`"doubleToLongBits("` .. dbl .. `")"`); System::out->println(String().plus(dbl)-> plus((dbl == dblret)?"==":"!=")-> plus(dblret)); System::out->println(`"doubleToRawLongBits("` .. dbl .. `")"`); System::out->println(String().plus(dbl)-> plus((dbl == dblrawret)?"==":"!=")-> plus(dblret)); } void doubleToStringTest(jdouble dbl) { System::out->println(`"Double::toString: "` .. Double::toString(dbl, 20)); } void floatToStringTest(jfloat flt) { System::out->println(`"Float::toString: "` .. Float::toString(flt)); } void floatTest() { tryParseDouble(`"1234.981"`); tryParseDouble(null); tryParseDouble(`"1234.981R"`); System::out->println(`" = "`->plus(new Double(0.00645))); doublelongTest(0.0); doublelongTest(0.000001); doublelongTest(0.123456); doublelongTest(7.654321); doublelongTest(9.999999); doubleToStringTest(0.12345678901234567890123456789); floatToStringTest((jfloat) 0.123456); doubleToStringTest(-0.123456789012345678901234567890); floatToStringTest((jfloat) -0.123456); doubleToStringTest(9.876543210987654321); floatToStringTest((jfloat) 9.876543); doubleToStringTest(-9.876532109876543210); floatToStringTest((jfloat) -9.876532); doubleToStringTest(-0.00000000000000000999); floatToStringTest((jfloat) -0.000999); //Inf jdouble d = 0.0, inf = 0.0; inf = 1.0/d; doubleToStringTest(inf); inf = -1.0/d; doubleToStringTest(inf); System::out->println(`"Double::isInfinite(1.0/0.0): "` .. Double::isInfinite(inf)); System::out->println(`"Double::isInfinite(1.0/1.0): "` .. Double::isInfinite(1.0/1.0)); System::out->println(`"Double::MAX_VALUE: "` .. Double::toString(Double::MAX_VALUE)); System::out->println(`"Double::MIN_VALUE: "` .. Double::toString(Double::MIN_VALUE)); System::out->println(`"Float::MAX_VALUE: "` .. Float::toString(Float::MAX_VALUE)); System::out->println(`"Float::MIN_VALUE: "` .. Float::toString(Float::MIN_VALUE)); } /** * This method shows usage of Hashtable and also includes basic * file input methods. */ void hashTest() { String* filename = params->getExePath() .. `"test/hash.conf"`; File inputFile(filename); Properties* p = new Properties(); System::out->println(`"Number of key/item pairs in hash: "` .. p->size() ..`" (isEmpty="` .. p->isEmpty() .. `")"`); try { System::out->println(`"Loading '"` .. inputFile.getPath() .. `"'"`); InputStreamReader reader(new FileInputStream(&inputFile), `"iso8859-1"`); BufferedReader bufferedReader = BufferedReader(&reader); p->load(&bufferedReader); reader.close(); } catch (Exception *ex) { System::out->println(ex); exit(1); } System::out->println(String("Number of key/item pairs in hash: ") .plus((jlong) p->size())->plus(" (isEmpty=")->plus((jlong) p->isEmpty()) ->plus(")")); System::out->println("Using HashtableIterator to go through all items in hash:"); HashtableIterator* it = p->keys(); while (it->hasNext()) { String* key = (String*) it->next(); String* value = (String*) p->get(key); System::out->println(String(" '").plus(key)->plus("' => '") ->plus(value)->plus("'")); } System::out->println(p); System::out->println("Doing some 'hash.put' and 'hash.remove' calls..."); p->put(new String("new entry"), new String("This is a new test entry.")); p->put(new String("3"), new String("This is the *NEW* number three.")); p->remove("0x0f"); System::out->println(String("Number of key/item pairs in hash: ") .plus((jlong) p->size())->plus(" (isEmpty=")->plus((jlong) p->isEmpty()) ->plus(")")); it = p->keys(); while (it->hasNext()) { String* key = (String*) it->next(); String* value = (String*) p->get(key); System::out->println(String(" '").plus(key)->plus("' => '") ->plus(value)->plus("'")); } System::out->println(p->toString()); } void processTest() { try { String* progName = System::file->getPath(); System::out->println(`"Starting native process: "`->plus(progName)); Process process(progName, `"--class"`, `"--number"`, null); InputStream* input = process.getInputStream(); InputStreamReader ir(input); BufferedReader reader(&ir); String* line; while (true) { line = reader.readLine(); if (line == null) { break; } System::out->print(">> "); System::out->println(line); } process.waitFor(); } catch (Exception *ex) { System::out->println(ex); } } void tryFilenameFilter(FilenameFilter *filter, File *dir, String *filename) { System::out->println(`" ::accept(\""` .. filename .. `"\") => "` .. Boolean::toString(filter->accept(dir, filename))); } void tryFilenameFilter(String *pattern, File *dir, ArrayList *filenames) { try { WildCardFilter *filter = new WildCardFilter(pattern); System::out->println(`""` .. filter .. `":"`); Iterator *it = filenames->iterator(); while (it->hasNext()) { tryFilenameFilter(filter, dir, (String*) it->next()); } } catch (Exception *ex) { System::out->println(ex); } } void fileFilterTest() { try { File dir(`"./"`); ArrayList *filenames = new ArrayList(); filenames->add(`"hello.txt"`); filenames->add(`"ab.txt"`); filenames->add(`"a.txt"`); filenames->add(`".txt"`); filenames->add(`"hello.cpp"`); filenames->add(`"Makefile"`); filenames->add(`"Makefile.am"`); filenames->add(`"Makefileam"`); filenames->add(`"M"`); tryFilenameFilter(`"*?.txt"`, &dir, filenames); tryFilenameFilter(`"Makefile*"`, &dir, filenames); tryFilenameFilter(`"*a*"`, &dir, filenames); tryFilenameFilter(`"*[Ml]*"`, &dir, filenames); tryFilenameFilter(`"[M.]*[a*"`, &dir, filenames); tryFilenameFilter(`"[M.]*?"`, &dir, filenames); tryFilenameFilter(`"Makefile?am"`, &dir, filenames); tryFilenameFilter(`"Makefile"`, &dir, filenames); tryFilenameFilter(`"*.{txt,am}"`, &dir, filenames); } catch (Exception *ex) { System::out->println(ex); } } void arrayListTest() { for (int idx = 0; idx < 1; idx++) { try { ArrayList* l = new ArrayList(); l->add(`"1st entry"`); l->add(`"This is the 2nd entry"`); l->add(null); l->add(`"And this is just the very last entry"`); System::out->println(l); l->remove(90); } catch (Exception *ex) { System::out->println(ex); } } } void allTests() { TEST_INFO *t = tests; while (t->name != null) { start(t->title); try { t->proc(); } catch (Exception *ex) { System::out->println(ex); } t++; } } void usageInfo() { TEST_INFO *t = tests; System::out->println(System::file->getName() .. `" - Available tests:\n"`); while (t->name != null) { System::out->printf(`" --%-20s %s\n"`, t->name, t->title); t++; } System::out->println(); exit(2); } int main(int argc, char* argv[]) { JAKELIB_INIT; params = new Commandline(argc, argv); if (params->size() == 0) { // Run all tests: dumpObjectCounter(); startTime = System::currentTimeMillis(); allTests(); } else { // Set-up commandline parser: TEST_INFO *t = tests; while (t->name != null) { String *name = new String(t->name); params->allowOption(name); t++; } // Are there any options left? -> Show usage info: if (params->size() > 0) { usageInfo(); } // Get current time: dumpObjectCounter(); startTime = System::currentTimeMillis(); // See which tests we wish to see: t = tests; while (t->name != null) { String *name = new String(t->name); if (params->optionSet(name)) { start(t->title); try { t->proc(); } catch (Exception *ex) { System::out->println(ex); } } t++; } } start(`"Forcing GC"`); dumpObjectCounter(); for (int idx = 0; idx < 3; idx++) gc(); dumpObjectCounter(); // JTEST_EXCEPTION(`"Test if this works"`, `"Hello, world!"`->substring(-1, -5), IllegalArgumentException); // JTEST_EXCEPTION(`"Test if this works"`, `"Hello, world!"`->substring(0, -1), IllegalArgumentException); // JTEST_RETURN_INT(`"Is the index correct?"`, `"Hello, world!"`->indexOf(`"world"`), 7); // JTEST_RETURN_INT(`"Is the index correct?"`, `"Hello, world!"`->indexOf(`"world"`), 7); // JTEST_RETURN_BOOLEAN(`"Is the index correct?"`, `"Hello, world!"`->equals(`"world"`), true); // JTEST_RETURN_OBJECT(`"Is the index correct?"`, `"Hello, world!"`->substring(7, 12), `"world"`); jtest_summary(); #ifdef MSVC Thread::sleep(10000); #endif if (failedTests == 0) { return 0; } else { return 1; } }