strutil_unittest.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <stdint.h>
  15. #include <string>
  16. #include <gtest/gtest.h>
  17. #include <util/strutil.h>
  18. using namespace isc;
  19. using namespace isc::util;
  20. using namespace std;
  21. // Check for slash replacement
  22. TEST(StringUtilTest, Slash) {
  23. string instring = "";
  24. isc::util::str::normalizeSlash(instring);
  25. EXPECT_EQ("", instring);
  26. instring = "C:\\A\\B\\C.D";
  27. isc::util::str::normalizeSlash(instring);
  28. EXPECT_EQ("C:/A/B/C.D", instring);
  29. instring = "// \\ //";
  30. isc::util::str::normalizeSlash(instring);
  31. EXPECT_EQ("// / //", instring);
  32. }
  33. // Check that leading and trailing space trimming works
  34. TEST(StringUtilTest, Trim) {
  35. // Empty and full string.
  36. EXPECT_EQ("", isc::util::str::trim(""));
  37. EXPECT_EQ("abcxyz", isc::util::str::trim("abcxyz"));
  38. // Trim right-most blanks
  39. EXPECT_EQ("ABC", isc::util::str::trim("ABC "));
  40. EXPECT_EQ("ABC", isc::util::str::trim("ABC\t\t \n\t"));
  41. // Left-most blank trimming
  42. EXPECT_EQ("XYZ", isc::util::str::trim(" XYZ"));
  43. EXPECT_EQ("XYZ", isc::util::str::trim("\t\t \tXYZ"));
  44. // Right and left, with embedded spaces
  45. EXPECT_EQ("MN \t OP", isc::util::str::trim("\t\tMN \t OP \t"));
  46. }
  47. // Check tokenization. Note that ASSERT_EQ is used to check the size of the
  48. // returned vector; if not as expected, the following references may be invalid
  49. // so should not be used.
  50. TEST(StringUtilTest, Tokens) {
  51. vector<string> result;
  52. // Default delimiters
  53. // Degenerate cases
  54. result = isc::util::str::tokens(""); // Empty string
  55. EXPECT_EQ(0, result.size());
  56. result = isc::util::str::tokens(" \n "); // String is all delimiters
  57. EXPECT_EQ(0, result.size());
  58. result = isc::util::str::tokens("abc"); // String has no delimiters
  59. ASSERT_EQ(1, result.size());
  60. EXPECT_EQ(string("abc"), result[0]);
  61. // String containing leading and/or trailing delimiters, no embedded ones.
  62. result = isc::util::str::tokens("\txyz"); // One leading delimiter
  63. ASSERT_EQ(1, result.size());
  64. EXPECT_EQ(string("xyz"), result[0]);
  65. result = isc::util::str::tokens("\t \nxyz"); // Multiple leading delimiters
  66. ASSERT_EQ(1, result.size());
  67. EXPECT_EQ(string("xyz"), result[0]);
  68. result = isc::util::str::tokens("xyz\n"); // One trailing delimiter
  69. ASSERT_EQ(1, result.size());
  70. EXPECT_EQ(string("xyz"), result[0]);
  71. result = isc::util::str::tokens("xyz \t"); // Multiple trailing
  72. ASSERT_EQ(1, result.size());
  73. EXPECT_EQ(string("xyz"), result[0]);
  74. result = isc::util::str::tokens("\t xyz \n"); // Leading and trailing
  75. ASSERT_EQ(1, result.size());
  76. EXPECT_EQ(string("xyz"), result[0]);
  77. // Embedded delimiters
  78. result = isc::util::str::tokens("abc\ndef"); // 2 tokens, one separator
  79. ASSERT_EQ(2, result.size());
  80. EXPECT_EQ(string("abc"), result[0]);
  81. EXPECT_EQ(string("def"), result[1]);
  82. result = isc::util::str::tokens("abc\t\t\ndef"); // 2 tokens, 3 separators
  83. ASSERT_EQ(2, result.size());
  84. EXPECT_EQ(string("abc"), result[0]);
  85. EXPECT_EQ(string("def"), result[1]);
  86. result = isc::util::str::tokens("abc\n \tdef\t\tghi");
  87. ASSERT_EQ(3, result.size()); // Multiple tokens, many delims
  88. EXPECT_EQ(string("abc"), result[0]);
  89. EXPECT_EQ(string("def"), result[1]);
  90. EXPECT_EQ(string("ghi"), result[2]);
  91. // Embedded and non-embedded delimiters
  92. result = isc::util::str::tokens("\t\t \nabc\n \tdef\t\tghi \n\n");
  93. ASSERT_EQ(3, result.size()); // Multiple tokens, many delims
  94. EXPECT_EQ(string("abc"), result[0]);
  95. EXPECT_EQ(string("def"), result[1]);
  96. EXPECT_EQ(string("ghi"), result[2]);
  97. // Non-default delimiter
  98. result = isc::util::str::tokens("alpha/beta/ /gamma//delta/epsilon/", "/");
  99. ASSERT_EQ(6, result.size());
  100. EXPECT_EQ(string("alpha"), result[0]);
  101. EXPECT_EQ(string("beta"), result[1]);
  102. EXPECT_EQ(string(" "), result[2]);
  103. EXPECT_EQ(string("gamma"), result[3]);
  104. EXPECT_EQ(string("delta"), result[4]);
  105. EXPECT_EQ(string("epsilon"), result[5]);
  106. // Non-default delimiters (plural)
  107. result = isc::util::str::tokens("+*--alpha*beta+ -gamma**delta+epsilon-+**",
  108. "*+-");
  109. ASSERT_EQ(6, result.size());
  110. EXPECT_EQ(string("alpha"), result[0]);
  111. EXPECT_EQ(string("beta"), result[1]);
  112. EXPECT_EQ(string(" "), result[2]);
  113. EXPECT_EQ(string("gamma"), result[3]);
  114. EXPECT_EQ(string("delta"), result[4]);
  115. EXPECT_EQ(string("epsilon"), result[5]);
  116. }
  117. // Changing case
  118. TEST(StringUtilTest, ChangeCase) {
  119. string mixed("abcDEFghiJKLmno123[]{=+--+]}");
  120. string upper("ABCDEFGHIJKLMNO123[]{=+--+]}");
  121. string lower("abcdefghijklmno123[]{=+--+]}");
  122. string test = mixed;
  123. isc::util::str::lowercase(test);
  124. EXPECT_EQ(lower, test);
  125. test = mixed;
  126. isc::util::str::uppercase(test);
  127. EXPECT_EQ(upper, test);
  128. }
  129. // Formatting
  130. TEST(StringUtilTest, Formatting) {
  131. vector<string> args;
  132. args.push_back("arg1");
  133. args.push_back("arg2");
  134. args.push_back("arg3");
  135. string format1 = "This is a string with no tokens";
  136. EXPECT_EQ(format1, isc::util::str::format(format1, args));
  137. string format2 = ""; // Empty string
  138. EXPECT_EQ(format2, isc::util::str::format(format2, args));
  139. string format3 = " "; // Empty string
  140. EXPECT_EQ(format3, isc::util::str::format(format3, args));
  141. string format4 = "String with %d non-string tokens %lf";
  142. EXPECT_EQ(format4, isc::util::str::format(format4, args));
  143. string format5 = "String with %s correct %s number of tokens %s";
  144. string result5 = "String with arg1 correct arg2 number of tokens arg3";
  145. EXPECT_EQ(result5, isc::util::str::format(format5, args));
  146. string format6 = "String with %s too %s few tokens";
  147. string result6 = "String with arg1 too arg2 few tokens";
  148. EXPECT_EQ(result6, isc::util::str::format(format6, args));
  149. string format7 = "String with %s too %s many %s tokens %s !";
  150. string result7 = "String with arg1 too arg2 many arg3 tokens %s !";
  151. EXPECT_EQ(result7, isc::util::str::format(format7, args));
  152. string format8 = "String with embedded%s%s%stokens";
  153. string result8 = "String with embeddedarg1arg2arg3tokens";
  154. EXPECT_EQ(result8, isc::util::str::format(format8, args));
  155. // Handle an empty vector
  156. args.clear();
  157. string format9 = "%s %s";
  158. EXPECT_EQ(format9, isc::util::str::format(format9, args));
  159. }
  160. TEST(StringUtilTest, getToken) {
  161. string s("a b c");
  162. istringstream ss(s);
  163. EXPECT_EQ("a", isc::util::str::getToken(ss));
  164. EXPECT_EQ("b", isc::util::str::getToken(ss));
  165. EXPECT_EQ("c", isc::util::str::getToken(ss));
  166. EXPECT_THROW(isc::util::str::getToken(ss), isc::util::str::StringTokenError);
  167. }
  168. int32_t tokenToNumCall_32_16(const string& token) {
  169. return isc::util::str::tokenToNum<int32_t, 16>(token);
  170. }
  171. int16_t tokenToNumCall_16_8(const string& token) {
  172. return isc::util::str::tokenToNum<int16_t, 8>(token);
  173. }
  174. TEST(StringUtilTest, tokenToNum) {
  175. uint32_t num32 = tokenToNumCall_32_16("0");
  176. EXPECT_EQ(0, num32);
  177. num32 = tokenToNumCall_32_16("123");
  178. EXPECT_EQ(123, num32);
  179. num32 = tokenToNumCall_32_16("65535");
  180. EXPECT_EQ(65535, num32);
  181. EXPECT_THROW(tokenToNumCall_32_16(""),
  182. isc::util::str::StringTokenError);
  183. EXPECT_THROW(tokenToNumCall_32_16("a"),
  184. isc::util::str::StringTokenError);
  185. EXPECT_THROW(tokenToNumCall_32_16("-1"),
  186. isc::util::str::StringTokenError);
  187. EXPECT_THROW(tokenToNumCall_32_16("65536"),
  188. isc::util::str::StringTokenError);
  189. EXPECT_THROW(tokenToNumCall_32_16("1234567890"),
  190. isc::util::str::StringTokenError);
  191. EXPECT_THROW(tokenToNumCall_32_16("-1234567890"),
  192. isc::util::str::StringTokenError);
  193. uint16_t num16 = tokenToNumCall_16_8("123");
  194. EXPECT_EQ(123, num16);
  195. num16 = tokenToNumCall_16_8("0");
  196. EXPECT_EQ(0, num16);
  197. num16 = tokenToNumCall_16_8("255");
  198. EXPECT_EQ(255, num16);
  199. EXPECT_THROW(tokenToNumCall_16_8(""),
  200. isc::util::str::StringTokenError);
  201. EXPECT_THROW(tokenToNumCall_16_8("a"),
  202. isc::util::str::StringTokenError);
  203. EXPECT_THROW(tokenToNumCall_16_8("-1"),
  204. isc::util::str::StringTokenError);
  205. EXPECT_THROW(tokenToNumCall_16_8("256"),
  206. isc::util::str::StringTokenError);
  207. EXPECT_THROW(tokenToNumCall_16_8("1234567890"),
  208. isc::util::str::StringTokenError);
  209. EXPECT_THROW(tokenToNumCall_16_8("-1234567890"),
  210. isc::util::str::StringTokenError);
  211. }