From 6245a68632875fb4a58eb5ca9fe2e321c171127b Mon Sep 17 00:00:00 2001 From: Tobia Tesan Date: Fri, 19 Apr 2013 17:00:12 +0200 Subject: TEST: Thorough testing for common/hash-str.h We test the various equal_to and hash functions therein. --- test/common/hash-str.h | 183 +++++++++++++++++++++++++++++++++++++++++++++++ test/common/huffman.h | 44 ++++++++---- test/common/rendermode.h | 5 +- test/common/util.h | 47 +++++++++--- 4 files changed, 250 insertions(+), 29 deletions(-) create mode 100644 test/common/hash-str.h (limited to 'test/common') diff --git a/test/common/hash-str.h b/test/common/hash-str.h new file mode 100644 index 0000000000..b106f66eda --- /dev/null +++ b/test/common/hash-str.h @@ -0,0 +1,183 @@ +#include +#include "common/hash-str.h" + +/** + * Test suite for common/hash-str.h + * We test a number of case sensitive/insensitive hash and compare functions + * using example strings and known hashes, trying to tackle + * as much edge cases as possible. + */ +class HashStrTestSuite : public CxxTest::TestSuite { + + public: + void test_case_sensitive_string_equal_to() { + + // Name says it all. + // This verifies that the function returns true + // for exactly the same string, false for the same + // string in mixed case and false for some edge cases + // with various spacings plus one character replaced + // by itself+128 (if there's some processing done after + // conversion to 7-bit ASCII this might yield funny results). + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const Common::String plus128("t\xE5est"); + // 'e'+128 = 0xE5 + + Common::CaseSensitiveString_EqualTo css_et; + TS_ASSERT_EQUALS(css_et(lower, mixed), false); + TS_ASSERT_EQUALS(css_et(lower, lower1), true); + TS_ASSERT_EQUALS(css_et(lower, lower), true); + + // Different sorts of whitespace are to be treated differently. + TS_ASSERT_EQUALS(css_et(lower, spaced), false); + TS_ASSERT_EQUALS(css_et(lower, tabbed), false); + TS_ASSERT_EQUALS(css_et(spaced, tabbed), false); + TS_ASSERT_EQUALS(css_et(spaced, doublespaced), false); + TS_ASSERT_EQUALS(css_et(lower, plus128), false); + } + + void test_ignore_case_equal_to() { + + // This should be probably called case_insensitive_string_equal_to + // or something,but it's basically the same thing as + // test_case_sensitive_string_equal_to, only it's case + // insensitive. + + const Common::String lower("test"); + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const Common::String plus128("t\xE5est"); + + Common::IgnoreCase_EqualTo ic_et; + TS_ASSERT_EQUALS(ic_et(lower, mixed), true); + TS_ASSERT_EQUALS(ic_et(lower, lower1), true); + TS_ASSERT_EQUALS(ic_et(lower, lower), true); + // Edge case: + TS_ASSERT_EQUALS(ic_et(spaced, mixedspaced), true); + + // Different sorts of whitespace are to be treated differently. + TS_ASSERT_EQUALS(ic_et(lower, spaced), false); + TS_ASSERT_EQUALS(ic_et(lower, tabbed), false); + TS_ASSERT_EQUALS(ic_et(spaced, tabbed), false); + TS_ASSERT_EQUALS(ic_et(spaced, doublespaced), false); + TS_ASSERT_EQUALS(ic_et(lower, plus128), false); + } + + void test_case_sensitive_string_hash() { + + // Here we compute string hashes for different + // strings and see that the functor is case sensitive + // and does not ignore spaces. + // The hashes come from Python's hash() function. + + const Common::String lower("test"); + const uint lower_hash = 1308370872; + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const uint mixed_hash = -1217273608; + const Common::String spaced("test "); + const uint spaced_hash = -1086267887; + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const uint tabbed_hash = -1086267848; + + Common::CaseSensitiveString_Hash css_h; + TS_ASSERT_EQUALS(css_h(lower), lower_hash); + TS_ASSERT_EQUALS(css_h(mixed), mixed_hash); + TS_ASSERT_EQUALS(css_h(spaced), spaced_hash); + TS_ASSERT_EQUALS(css_h(tabbed), tabbed_hash); + TS_ASSERT_DIFFERS(css_h(spaced), css_h(doublespaced)); + } + + void test_ignore_case_hash() { + // Same as test_case_sensitive_string_hash, but case insensitive. + const Common::String lower("test"); + const uint lower_hash = 1308370872; + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const Common::String spaced("test "); + const uint spaced_hash = -1086267887; + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const uint tabbed_hash = -1086267848; + + Common::IgnoreCase_Hash ic_h; + TS_ASSERT_EQUALS(ic_h(lower), lower_hash); + TS_ASSERT_EQUALS(ic_h(mixed), lower_hash); + TS_ASSERT_EQUALS(ic_h(spaced), spaced_hash); + TS_ASSERT_EQUALS(ic_h(tabbed), tabbed_hash); + TS_ASSERT_EQUALS(ic_h(mixedspaced), spaced_hash); + TS_ASSERT_DIFFERS(ic_h(spaced), ic_h(doublespaced)); + } + + void test_cpp_string_hash () + { + // We run the same tests with Hash, + // a template specialization of Hash, also a functor. + // It is supposed to be case sensitive. + // Again, hashes come from Python's hash(). + + const Common::String lower("test"); + const uint lower_hash = 1308370872; + const Common::String lower1("test"); + const Common::String mixed("tESt"); + const uint mixed_hash = -1217273608; + const Common::String spaced("test "); + const uint spaced_hash = -1086267887; + const Common::String mixedspaced("tESt "); + const Common::String doublespaced("test "); + const Common::String tabbed("test\t"); + const uint tabbed_hash = -1086267848; + + Common::Hash h; + TS_ASSERT_EQUALS(h(lower), lower_hash); + TS_ASSERT_EQUALS(h(lower), h(lower1)); + TS_ASSERT_EQUALS(h(mixed), mixed_hash); + TS_ASSERT_EQUALS(h(spaced), spaced_hash); + TS_ASSERT_EQUALS(h(tabbed), tabbed_hash); + TS_ASSERT_DIFFERS(h(spaced), h(doublespaced)); + } + + void test_c_style_string_hash () + { + // Same as test_cpp_string_hash but with Hash, + // a template specialization of Hash, also a functor, + // that works with C-Style strings. + // It is supposed to be case sensitive. + + char lower[] = "test"; + const uint lower_hash = 1308370872; // CPython told me so + char lower1[] = "test"; + char mixed[] = "tESt"; + const uint mixed_hash = -1217273608; + char spaced[] = "test "; + const uint spaced_hash = -1086267887; + char mixedspaced[] = "tESt "; + char doublespaced[] = "test "; + char tabbed[] = "test\t"; + const uint tabbed_hash = -1086267848; + + Common::Hash h; + TS_ASSERT_EQUALS(h(lower), lower_hash); + TS_ASSERT_EQUALS(h(lower), h(lower1)); + TS_ASSERT_EQUALS(h(mixed), mixed_hash); + TS_ASSERT_EQUALS(h(spaced), spaced_hash); + TS_ASSERT_DIFFERS(h(spaced), h(mixedspaced)); + TS_ASSERT_EQUALS(h(tabbed), tabbed_hash); + TS_ASSERT_DIFFERS(h(spaced), h(doublespaced)); + } + + +}; diff --git a/test/common/huffman.h b/test/common/huffman.h index 52199a8ffd..53353aaa60 100644 --- a/test/common/huffman.h +++ b/test/common/huffman.h @@ -3,20 +3,27 @@ #include "common/bitstream.h" #include "common/memstream.h" -class HuffmanTestSuite : public CxxTest::TestSuite -{ +/** +* A test suite for the Huffman decoder in common/huffman.h +* The encoding used comes from the example on the Wikipedia page +* for Huffman. +* TODO: It could be improved by generating one at runtime. +*/ +class HuffmanTestSuite : public CxxTest::TestSuite { public: void test_get_with_full_symbols() { /* - * Testing the Huffman decoder. + * The class can be initialized with or without providing + * a max_length and a symbol table. + * We test with a table. * * Encoding (arbitrary, for testing purpouses): - * A=010 - * B=011 - * C=11 - * D=00 - * E=10 + * 0xA=010 + * 0xB=011 + * 0xC=11 + * 0xD=00 + * 0xE=10 */ uint32 codeCount = 5; @@ -25,7 +32,7 @@ class HuffmanTestSuite : public CxxTest::TestSuite const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE}; - Common::Huffman h (maxLength, codeCount, codes, lengths, symbols); + Common::Huffman h(maxLength, codeCount, codes, lengths, symbols); byte input[] = {0x4F, 0x20}; // Provided input... @@ -53,8 +60,8 @@ class HuffmanTestSuite : public CxxTest::TestSuite void test_get_without_symbols() { /* - * This is basically the same as above, but - * I pass minimal arguments. + * This is basically the same as test_get_with_full_symbols, but + * I only pass the minimal required arguments. * Specifically, I avoid passing the symbols table, so that * array indices are used instead. * @@ -71,7 +78,7 @@ class HuffmanTestSuite : public CxxTest::TestSuite const uint8 lengths[] = {3,3,2,2,2}; const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; - Common::Huffman h (0, codeCount, codes, lengths, 0); + Common::Huffman h(0, codeCount, codes, lengths, 0); byte input[] = {0x4F, 0x20}; uint32 expected[] = {0, 1, 2, 3, 4, 3 ,3}; @@ -91,16 +98,23 @@ class HuffmanTestSuite : public CxxTest::TestSuite void test_get_after_set_symbols() { /* - * Another variation of the above. + * Another variation of test_get_with_full_symbols. * I use the setSymbols method to define, a posteriori, - * an alphabet to be used in place of array indices + * an alphabet to be used in place of array indices. + * The encoding is, at first, + * 0=010 + * 1=011 + * 2=11 + * 3=00 + * 4=10 + * (=array indices). */ uint32 codeCount = 5; const uint8 lengths[] = {3,3,2,2,2}; const uint32 codes[] = {0x2, 0x3, 0x3, 0x0, 0x2}; - Common::Huffman h (0, codeCount, codes, lengths, 0); + Common::Huffman h(0, codeCount, codes, lengths, 0); const uint32 symbols[] = {0xA, 0xB, 0xC, 0xD, 0xE}; h.setSymbols(symbols); diff --git a/test/common/rendermode.h b/test/common/rendermode.h index a25c0982ed..e5e277f16b 100644 --- a/test/common/rendermode.h +++ b/test/common/rendermode.h @@ -3,8 +3,7 @@ #include "common/gui_options.h" #include "common/str.h" -class RenderModeTestSuite : public CxxTest::TestSuite -{ +class RenderModeTestSuite : public CxxTest::TestSuite { public: void test_parse_render_mode_good() { /* @@ -63,7 +62,7 @@ class RenderModeTestSuite : public CxxTest::TestSuite TS_ASSERT_EQUALS(Common::getRenderModeCode(Common::kRenderDefault), null_p); } - void test_render_2_guio () { + void test_render_2_guio() { /* * Verify that a rendermode is taken and the corresponding * GUIO_xxxxx is returned. diff --git a/test/common/util.h b/test/common/util.h index 3bd997a38f..57688ff30b 100644 --- a/test/common/util.h +++ b/test/common/util.h @@ -1,16 +1,16 @@ #include #include "common/util.h" +/** + * Test suite for the functions in common/util.h + */ class UtilTestSuite : public CxxTest::TestSuite { -public: - - // Test the parseBool function - - // 'Regular' cases that must work - // (note that the function must be case insensitive): - + public: void test_parsebool_yesno() { + // First test for the parseBool function. + // These are the mixed case yes/no cases that must work + bool valasbool; bool success; @@ -27,6 +27,9 @@ public: void test_parsebool_truefalse() { + // First test for the parseBool function. + // These are the mixed case true/false cases that must work + bool valasbool; bool success; @@ -43,6 +46,12 @@ public: void test_parsebool_onezero() { + // Third test for the parseBool function. + // These are the 1/0 cases that must work. + // Note that while 'a-z'+0x20 must work just fine, + // '0-1'+0x20 should NOT; this is addressed in + // parsebool_bad + bool valasbool; bool success; @@ -79,6 +88,20 @@ public: success = Common::parseBool (string_3, valasbool); TS_ASSERT_EQUALS(success, 0); + // While 'a-z'+0x20 must work just fine, + // '0-1'+0x20 should NOT. '2' is not good either. + + Common::String string_4 ("\x50"); + success = Common::parseBool (string_4, valasbool); + TS_ASSERT_EQUALS(success, 0); + + Common::String string_5 ("\x51"); + success = Common::parseBool (string_5, valasbool); + TS_ASSERT_EQUALS(success, 0); + + Common::String string_6 ("2"); + success = Common::parseBool (string_6, valasbool); + TS_ASSERT_EQUALS(success, 0); } void test_is_al_num() { @@ -189,8 +212,10 @@ public: void test_is_space() { // isSpace should return true iff the character is some kind of whitespace // or tab character - for (int c=0; c<255; c++) { - if (c==' ' || c=='\t' || c=='\r' || c=='\n' || c=='\v' || c=='\f') { + for (int c = 0; c < 255; c++) { + if (c == ' ' || c == '\t' || + c == '\r' || c == '\n' || + c == '\v' || c == '\f') { TS_ASSERT_EQUALS(Common::isSpace(c), 1); } else { TS_ASSERT_EQUALS(Common::isSpace(c), 0); @@ -201,8 +226,8 @@ public: void test_is_print() { // isPrint should return true iff the input is a printable ascii char. // That is to say, 0x20 to 0x7E. - for (int c=0; c<255; c++) { - if (c>=0x20 && c<=0x7E) { + for (int c = 0; c < 255; c++) { + if (c >= 0x20 && c <= 0x7E) { TS_ASSERT_EQUALS(Common::isPrint(c), 1); } else { TS_ASSERT_EQUALS(Common::isPrint(c), 0); -- cgit v1.2.3