diff options
author | Mike Buland <eichlan@xagasoft.com> | 2006-05-26 14:36:57 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2006-05-26 14:36:57 +0000 |
commit | a820665eea71a64b40e74ed24afeaf07a7a99db4 (patch) | |
tree | 515af31ac2ed78aa92ce7e90e478bdb452e6e438 /src | |
parent | bd5bb1ca60a6a97b110cbf221b3625e6e6200141 (diff) | |
download | libbu++-a820665eea71a64b40e74ed24afeaf07a7a99db4.tar.gz libbu++-a820665eea71a64b40e74ed24afeaf07a7a99db4.tar.bz2 libbu++-a820665eea71a64b40e74ed24afeaf07a7a99db4.tar.xz libbu++-a820665eea71a64b40e74ed24afeaf07a7a99db4.zip |
Added the first of many unit tests. For now the unit tests are just built with
everything else in the all target of the makefile, which is fine, but relies on
CppTest, which can be found at http://cpptest.sf.net
Also fixed some things I've been meaning to get to for a while in the xml
system, including a few bugs that will make coping with malformed data not hang
other programs, and do the error reporting in a nice way.
Diffstat (limited to '')
-rw-r--r-- | src/exception.cpp | 13 | ||||
-rw-r--r-- | src/unit/hashtable.cpp | 107 | ||||
-rw-r--r-- | src/unit/xml.cpp | 43 | ||||
-rw-r--r-- | src/xmlexception.cpp | 27 | ||||
-rw-r--r-- | src/xmlexception.h | 34 | ||||
-rw-r--r-- | src/xmlfilereader.cpp | 5 | ||||
-rw-r--r-- | src/xmlreader.cpp | 38 | ||||
-rw-r--r-- | src/xmlreader.h | 14 | ||||
-rw-r--r-- | src/xmlstringreader.cpp | 3 |
9 files changed, 237 insertions, 47 deletions
diff --git a/src/exception.cpp b/src/exception.cpp index 291a198..3cde134 100644 --- a/src/exception.cpp +++ b/src/exception.cpp | |||
@@ -2,7 +2,8 @@ | |||
2 | #include <stdarg.h> | 2 | #include <stdarg.h> |
3 | 3 | ||
4 | Exception::Exception( const char *lpFormat, ... ) throw() : | 4 | Exception::Exception( const char *lpFormat, ... ) throw() : |
5 | nErrorCode( 0 ) | 5 | nErrorCode( 0 ), |
6 | sWhat( NULL ) | ||
6 | { | 7 | { |
7 | va_list ap; | 8 | va_list ap; |
8 | 9 | ||
@@ -12,7 +13,8 @@ Exception::Exception( const char *lpFormat, ... ) throw() : | |||
12 | } | 13 | } |
13 | 14 | ||
14 | Exception::Exception( int nCode, const char *lpFormat, ... ) throw() : | 15 | Exception::Exception( int nCode, const char *lpFormat, ... ) throw() : |
15 | nErrorCode( nCode ) | 16 | nErrorCode( nCode ), |
17 | sWhat( NULL ) | ||
16 | { | 18 | { |
17 | va_list ap; | 19 | va_list ap; |
18 | 20 | ||
@@ -29,11 +31,16 @@ Exception::Exception( int nCode ) throw() : | |||
29 | 31 | ||
30 | Exception::~Exception() throw() | 32 | Exception::~Exception() throw() |
31 | { | 33 | { |
32 | delete[] sWhat; | 34 | if( sWhat ) |
35 | { | ||
36 | delete[] sWhat; | ||
37 | sWhat = NULL; | ||
38 | } | ||
33 | } | 39 | } |
34 | 40 | ||
35 | void Exception::setWhat( const char *lpFormat, va_list &vargs ) | 41 | void Exception::setWhat( const char *lpFormat, va_list &vargs ) |
36 | { | 42 | { |
43 | if( sWhat ) delete[] sWhat; | ||
37 | int nSize; | 44 | int nSize; |
38 | 45 | ||
39 | nSize = vsnprintf( NULL, 0, lpFormat, vargs ); | 46 | nSize = vsnprintf( NULL, 0, lpFormat, vargs ); |
diff --git a/src/unit/hashtable.cpp b/src/unit/hashtable.cpp new file mode 100644 index 0000000..b2e1cf5 --- /dev/null +++ b/src/unit/hashtable.cpp | |||
@@ -0,0 +1,107 @@ | |||
1 | #include <cstdlib> | ||
2 | #include <cstring> | ||
3 | #include <iostream> | ||
4 | #include <cpptest.h> | ||
5 | #include <string.h> | ||
6 | #include <set> | ||
7 | #include <map> | ||
8 | |||
9 | #include "hashfunctionstring.h" | ||
10 | #include "hashfunctioncasestring.h" | ||
11 | #include "hashfunctionint.h" | ||
12 | |||
13 | class HashFunctionSuite : public Test::Suite | ||
14 | { | ||
15 | public: | ||
16 | HashFunctionSuite() | ||
17 | { | ||
18 | TEST_ADD( HashFunctionSuite::functionString ) | ||
19 | TEST_ADD( HashFunctionSuite::functionCaseString ) | ||
20 | TEST_ADD( HashFunctionSuite::functionInt ) | ||
21 | } | ||
22 | |||
23 | private: | ||
24 | void functionStringWorker( HashFunction &hf, std::set<unsigned long> &sCodes, char *str, int nLevel, int nMax ) | ||
25 | { | ||
26 | for( char let = 'A'; let <= 'z'; let += 3 ) | ||
27 | { | ||
28 | str[nLevel+1] = '\0'; | ||
29 | str[nLevel] = let; | ||
30 | unsigned long x = hf.hash( str ); | ||
31 | TEST_ASSERT( sCodes.find( x ) == sCodes.end() ); | ||
32 | TEST_ASSERT( hf.cmpIDs( str, str ) ); | ||
33 | sCodes.insert( x ); | ||
34 | |||
35 | if( nLevel < nMax ) | ||
36 | functionStringWorker( hf, sCodes, str, nLevel+1, nMax ); | ||
37 | } | ||
38 | } | ||
39 | |||
40 | void functionString() | ||
41 | { | ||
42 | HashFunctionString hf; | ||
43 | char str[10]; | ||
44 | |||
45 | std::set<unsigned long> sCodes; | ||
46 | |||
47 | functionStringWorker( hf, sCodes, str, 0, 3 ); | ||
48 | } | ||
49 | |||
50 | void functionCaseStringWorker( HashFunction &hf, std::map<unsigned long, char *> &sCodes, char *str, int nLevel, int nMax ) | ||
51 | { | ||
52 | for( char let = 'A'; let <= 'z'; let += 3 ) | ||
53 | { | ||
54 | str[nLevel+1] = '\0'; | ||
55 | str[nLevel] = let; | ||
56 | unsigned long x = hf.hash( str ); | ||
57 | std::map<unsigned long, char *>::iterator i = sCodes.find( x ); | ||
58 | if( i == sCodes.end() ) | ||
59 | { | ||
60 | sCodes[x] = strdup( str ); | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | TEST_ASSERT( strcasecmp( (*i).second, str ) == 0 ); | ||
65 | TEST_ASSERT( hf.cmpIDs( (*i).second, str ) == true ); | ||
66 | } | ||
67 | |||
68 | if( nLevel < nMax ) | ||
69 | functionCaseStringWorker( hf, sCodes, str, nLevel+1, nMax ); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void functionCaseString() | ||
74 | { | ||
75 | HashFunctionCaseString hf; | ||
76 | char str[10]; | ||
77 | |||
78 | std::map<unsigned long, char *> sCodes; | ||
79 | |||
80 | functionCaseStringWorker( hf, sCodes, str, 0, 3 ); | ||
81 | |||
82 | std::map<unsigned long, char *>::iterator i; | ||
83 | for( i = sCodes.begin(); i != sCodes.end(); i++ ) | ||
84 | { | ||
85 | free( (*i).second ); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | void functionInt() | ||
90 | { | ||
91 | HashFunctionInt hf; | ||
92 | |||
93 | for( long i = -100000; i <= 100000; i += 100 ) | ||
94 | { | ||
95 | TEST_ASSERT( ((long)hf.hash( (void *)i )) == i ); | ||
96 | TEST_ASSERT( ((long)hf.cmpIDs( (void *)i, (void *)i )) ); | ||
97 | } | ||
98 | } | ||
99 | }; | ||
100 | |||
101 | int main( int argc, char *argv[] ) | ||
102 | { | ||
103 | Test::TextOutput output( Test::TextOutput::Verbose ); | ||
104 | HashFunctionSuite ts; | ||
105 | return ts.run( output ) ? EXIT_SUCCESS : EXIT_FAILURE; | ||
106 | } | ||
107 | |||
diff --git a/src/unit/xml.cpp b/src/unit/xml.cpp new file mode 100644 index 0000000..559b2f4 --- /dev/null +++ b/src/unit/xml.cpp | |||
@@ -0,0 +1,43 @@ | |||
1 | #include <cstdlib> | ||
2 | #include <cstring> | ||
3 | #include <iostream> | ||
4 | #include <cpptest.h> | ||
5 | #include <string.h> | ||
6 | |||
7 | #include "xmlstringreader.h" | ||
8 | #include "xmlexception.h" | ||
9 | |||
10 | class XmlCoreTestSuite : public Test::Suite | ||
11 | { | ||
12 | public: | ||
13 | XmlCoreTestSuite() | ||
14 | { | ||
15 | TEST_ADD( XmlCoreTestSuite::badXml01 ) | ||
16 | TEST_ADD( XmlCoreTestSuite::badXml02 ) | ||
17 | TEST_ADD( XmlCoreTestSuite::badXml03 ) | ||
18 | } | ||
19 | |||
20 | private: | ||
21 | void badXml01() | ||
22 | { | ||
23 | TEST_THROWS( XmlStringReader r("<hello></bye>"), XmlException & ); | ||
24 | } | ||
25 | |||
26 | void badXml02() | ||
27 | { | ||
28 | TEST_THROWS( XmlStringReader r("<hello>"), XmlException & ); | ||
29 | } | ||
30 | |||
31 | void badXml03() | ||
32 | { | ||
33 | TEST_THROWS( XmlStringReader r("<hello param=\"stuff?"), XmlException & ); | ||
34 | } | ||
35 | }; | ||
36 | |||
37 | int main( int argc, char *argv[] ) | ||
38 | { | ||
39 | Test::TextOutput output( Test::TextOutput::Verbose ); | ||
40 | XmlCoreTestSuite ts; | ||
41 | return ts.run( output ) ? EXIT_SUCCESS : EXIT_FAILURE; | ||
42 | } | ||
43 | |||
diff --git a/src/xmlexception.cpp b/src/xmlexception.cpp new file mode 100644 index 0000000..7012ee6 --- /dev/null +++ b/src/xmlexception.cpp | |||
@@ -0,0 +1,27 @@ | |||
1 | #include "xmlexception.h" | ||
2 | #include <stdarg.h> | ||
3 | |||
4 | XmlException::XmlException( const char *lpFormat, ... ) throw() : | ||
5 | Exception( 0 ) | ||
6 | { | ||
7 | va_list ap; | ||
8 | |||
9 | va_start(ap, lpFormat); | ||
10 | setWhat( lpFormat, ap ); | ||
11 | va_end(ap); | ||
12 | } | ||
13 | |||
14 | XmlException::XmlException( int nCode, const char *lpFormat, ... ) throw() : | ||
15 | Exception( nCode ) | ||
16 | { | ||
17 | va_list ap; | ||
18 | |||
19 | va_start(ap, lpFormat); | ||
20 | setWhat( lpFormat, ap ); | ||
21 | va_end(ap); | ||
22 | } | ||
23 | |||
24 | XmlException::XmlException( int nCode ) throw() : | ||
25 | Exception( nCode ) | ||
26 | { | ||
27 | } | ||
diff --git a/src/xmlexception.h b/src/xmlexception.h new file mode 100644 index 0000000..9437ba3 --- /dev/null +++ b/src/xmlexception.h | |||
@@ -0,0 +1,34 @@ | |||
1 | #ifndef XML_EXCEPTION_H | ||
2 | #define XML_EXCEPTION_H | ||
3 | |||
4 | #include <string> | ||
5 | #include "exception.h" | ||
6 | #include <stdarg.h> | ||
7 | |||
8 | /** | ||
9 | * A generalized Exception base class. This is nice for making general and | ||
10 | * flexible child classes that can create new error code classes. | ||
11 | */ | ||
12 | class XmlException : public Exception | ||
13 | { | ||
14 | public: | ||
15 | /** | ||
16 | * Construct an exception with an error code of zero, but with a | ||
17 | * description. The use of this is not reccomended most of the time, it's | ||
18 | * generally best to include an error code with the exception so your | ||
19 | * program can handle the exception in a better way. | ||
20 | * @param sFormat The format of the text. See printf for more info. | ||
21 | */ | ||
22 | XmlException( const char *sFormat, ... ) throw(); | ||
23 | |||
24 | /** | ||
25 | * | ||
26 | * @param nCode | ||
27 | * @param sFormat | ||
28 | */ | ||
29 | XmlException( int nCode, const char *sFormat, ... ) throw(); | ||
30 | |||
31 | XmlException( int nCode=0 ) throw(); | ||
32 | }; | ||
33 | |||
34 | #endif | ||
diff --git a/src/xmlfilereader.cpp b/src/xmlfilereader.cpp index 216c08a..dd4bc82 100644 --- a/src/xmlfilereader.cpp +++ b/src/xmlfilereader.cpp | |||
@@ -1,4 +1,5 @@ | |||
1 | #include "xmlfilereader.h" | 1 | #include "xmlfilereader.h" |
2 | #include "xmlexception.h" | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | 4 | ||
4 | XmlFileReader::XmlFileReader( const char *sFile, bool bStrip ) | 5 | XmlFileReader::XmlFileReader( const char *sFile, bool bStrip ) |
@@ -8,7 +9,7 @@ XmlFileReader::XmlFileReader( const char *sFile, bool bStrip ) | |||
8 | 9 | ||
9 | if( fh == NULL ) | 10 | if( fh == NULL ) |
10 | { | 11 | { |
11 | reportError("Couldn't open file."); | 12 | throw XmlException("Couldn't open file: %s", sFile ); |
12 | //nError = 1; | 13 | //nError = 1; |
13 | } | 14 | } |
14 | else | 15 | else |
@@ -50,7 +51,7 @@ char XmlFileReader::getChar( int nIndex ) | |||
50 | } | 51 | } |
51 | else | 52 | else |
52 | { | 53 | { |
53 | return '\0'; | 54 | throw XmlException("End of XML stream read."); |
54 | } | 55 | } |
55 | } | 56 | } |
56 | 57 | ||
diff --git a/src/xmlreader.cpp b/src/xmlreader.cpp index bb24157..76c6258 100644 --- a/src/xmlreader.cpp +++ b/src/xmlreader.cpp | |||
@@ -1,10 +1,10 @@ | |||
1 | #include "xmlreader.h" | 1 | #include "xmlreader.h" |
2 | #include "xmlexception.h" | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | 4 | ||
4 | XmlReader::XmlReader( bool bStrip ) | 5 | XmlReader::XmlReader( bool bStrip ) : |
6 | bStrip( bStrip ) | ||
5 | { | 7 | { |
6 | nError = 0; | ||
7 | this->bStrip = bStrip; | ||
8 | } | 8 | } |
9 | 9 | ||
10 | XmlReader::~XmlReader() | 10 | XmlReader::~XmlReader() |
@@ -68,13 +68,12 @@ bool XmlReader::node() | |||
68 | } | 68 | } |
69 | else | 69 | else |
70 | { | 70 | { |
71 | reportError("Close node in singleNode malformed!"); | 71 | throw XmlException("Close node in singleNode malformed!"); |
72 | return false; | ||
73 | } | 72 | } |
74 | } | 73 | } |
75 | else | 74 | else |
76 | { | 75 | { |
77 | reportError("Close node expected, but not found."); | 76 | throw XmlException("Close node expected, but not found."); |
78 | return false; | 77 | return false; |
79 | } | 78 | } |
80 | 79 | ||
@@ -108,8 +107,7 @@ bool XmlReader::startNode() | |||
108 | } | 107 | } |
109 | else | 108 | else |
110 | { | 109 | { |
111 | reportError("Got a mismatched node close tag."); | 110 | throw XmlException("Got a mismatched node close tag."); |
112 | return false; | ||
113 | } | 111 | } |
114 | } | 112 | } |
115 | else | 113 | else |
@@ -127,8 +125,7 @@ bool XmlReader::startNode() | |||
127 | } | 125 | } |
128 | else | 126 | else |
129 | { | 127 | { |
130 | reportError("Got extra junk data instead of node close tag."); | 128 | throw XmlException("Got extra junk data instead of node close tag."); |
131 | return false; | ||
132 | } | 129 | } |
133 | } | 130 | } |
134 | else | 131 | else |
@@ -146,8 +143,7 @@ bool XmlReader::startNode() | |||
146 | } | 143 | } |
147 | else | 144 | else |
148 | { | 145 | { |
149 | reportError("Expected to find node opening char, '<'.\n"); | 146 | throw XmlException("Expected to find node opening char, '<'."); |
150 | return false; | ||
151 | } | 147 | } |
152 | 148 | ||
153 | return true; | 149 | return true; |
@@ -306,7 +302,7 @@ bool XmlReader::param() | |||
306 | } | 302 | } |
307 | else | 303 | else |
308 | { | 304 | { |
309 | reportError("Expected an equals to seperate the params."); | 305 | throw XmlException("Expected an equals to seperate the params."); |
310 | return false; | 306 | return false; |
311 | } | 307 | } |
312 | 308 | ||
@@ -352,8 +348,7 @@ bool XmlReader::content() | |||
352 | } | 348 | } |
353 | else | 349 | else |
354 | { | 350 | { |
355 | reportError("Mismatched close tag found."); | 351 | throw XmlException("Mismatched close tag found: <%s> to <%s>.", getCurrent()->getName(), fbName.getData() ); |
356 | return false; | ||
357 | } | 352 | } |
358 | } | 353 | } |
359 | else | 354 | else |
@@ -370,8 +365,7 @@ bool XmlReader::content() | |||
370 | } | 365 | } |
371 | else | 366 | else |
372 | { | 367 | { |
373 | reportError("Malformed close tag."); | 368 | throw XmlException("Malformed close tag."); |
374 | return false; | ||
375 | } | 369 | } |
376 | } | 370 | } |
377 | else | 371 | else |
@@ -400,13 +394,3 @@ bool XmlReader::content() | |||
400 | } | 394 | } |
401 | } | 395 | } |
402 | 396 | ||
403 | void XmlReader::reportError( const char *sError ) | ||
404 | { | ||
405 | printf("XmlReader error: %s\n", sError ); | ||
406 | } | ||
407 | |||
408 | int XmlReader::getError() | ||
409 | { | ||
410 | return nError; | ||
411 | } | ||
412 | |||
diff --git a/src/xmlreader.h b/src/xmlreader.h index a8a81f0..19e485a 100644 --- a/src/xmlreader.h +++ b/src/xmlreader.h | |||
@@ -38,19 +38,6 @@ public: | |||
38 | ~XmlReader(); | 38 | ~XmlReader(); |
39 | 39 | ||
40 | /** | 40 | /** |
41 | * Get the error code if an error happened. | ||
42 | *@returns The error code (I don't know what they are either) | ||
43 | */ | ||
44 | int getError(); | ||
45 | |||
46 | /** | ||
47 | * Report an error to something, this is a really strange mechanism and | ||
48 | * should probably just be replaced with the multi-log system. | ||
49 | *@param sError The error to report. | ||
50 | */ | ||
51 | void reportError( const char *sError ); | ||
52 | |||
53 | /** | ||
54 | * Build a document based on some kind of input. This is called | 41 | * Build a document based on some kind of input. This is called |
55 | * automatically by the constructor. | 42 | * automatically by the constructor. |
56 | */ | 43 | */ |
@@ -127,7 +114,6 @@ private: | |||
127 | FlexBuf fbParamName; /**< buffer for the current param's name. */ | 114 | FlexBuf fbParamName; /**< buffer for the current param's name. */ |
128 | FlexBuf fbParamValue; /**< buffer for the current param's value. */ | 115 | FlexBuf fbParamValue; /**< buffer for the current param's value. */ |
129 | bool bStrip; /**< Are we stripping whitespace? */ | 116 | bool bStrip; /**< Are we stripping whitespace? */ |
130 | int nError; /**< Is there an error? */ | ||
131 | }; | 117 | }; |
132 | 118 | ||
133 | #endif | 119 | #endif |
diff --git a/src/xmlstringreader.cpp b/src/xmlstringreader.cpp index aa7174f..82caacd 100644 --- a/src/xmlstringreader.cpp +++ b/src/xmlstringreader.cpp | |||
@@ -1,4 +1,5 @@ | |||
1 | #include "xmlstringreader.h" | 1 | #include "xmlstringreader.h" |
2 | #include "xmlexception.h" | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | 4 | ||
4 | XmlStringReader::XmlStringReader( const char *sString, bool bStrip ) | 5 | XmlStringReader::XmlStringReader( const char *sString, bool bStrip ) |
@@ -24,7 +25,7 @@ char XmlStringReader::getChar( int nAdd ) | |||
24 | } | 25 | } |
25 | else | 26 | else |
26 | { | 27 | { |
27 | return '\0'; | 28 | throw XmlException("End of XML stream read."); |
28 | } | 29 | } |
29 | } | 30 | } |
30 | 31 | ||