StringBuilderTest.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550
  1. // -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
  2. //
  3. // StringBuilderTest.dll - NUnit Test Cases for the System.Text.StringBuilder class
  4. //
  5. // Author: Marcin Szczepanski ([email protected])
  6. //
  7. // NOTES: I've also run all these tests against the MS implementation of
  8. // System.Text.StringBuilder to confirm that they return the same results
  9. // and they do.
  10. //
  11. // TODO: Add tests for the AppendFormat methods once the AppendFormat methods
  12. // are implemented in the StringBuilder class itself
  13. //
  14. // TODO: Potentially add more variations on Insert / Append tests for all the
  15. // possible types. I don't really think that's necessary as they all
  16. // pretty much just do .ToString().ToCharArray() and then use the Append / Insert
  17. // CharArray function. The ToString() bit for each type should be in the unit
  18. // tests for those types, and the unit test for ToCharArray should be in the
  19. // string test type. If someone wants to add those tests here for completness
  20. // (and some double checking) then feel free :)
  21. //
  22. using NUnit.Framework;
  23. using System.Text;
  24. using System;
  25. namespace MonoTests.System.Text {
  26. [TestFixture]
  27. public class StringBuilderTest {
  28. private StringBuilder sb;
  29. [Test]
  30. public void TestConstructor1()
  31. {
  32. // check the parameterless ctor
  33. sb = new StringBuilder();
  34. Assert.AreEqual(String.Empty, sb.ToString());
  35. Assert.AreEqual(0, sb.Length);
  36. Assert.AreEqual(16, sb.Capacity);
  37. }
  38. [Test]
  39. public void TestConstructor2()
  40. {
  41. // check ctor that specifies the capacity
  42. sb = new StringBuilder(10);
  43. Assert.AreEqual(String.Empty, sb.ToString());
  44. Assert.AreEqual(0, sb.Length);
  45. // check that capacity is not less than default
  46. Assert.AreEqual(10, sb.Capacity);
  47. sb = new StringBuilder(42);
  48. Assert.AreEqual(String.Empty, sb.ToString());
  49. Assert.AreEqual(0, sb.Length);
  50. // check that capacity is set
  51. Assert.AreEqual(42, sb.Capacity);
  52. }
  53. [Test]
  54. public void TestConstructor3() {
  55. // check ctor that specifies the capacity & maxCapacity
  56. sb = new StringBuilder(444, 1234);
  57. Assert.AreEqual(String.Empty, sb.ToString());
  58. Assert.AreEqual(0, sb.Length);
  59. Assert.AreEqual(444, sb.Capacity);
  60. Assert.AreEqual(1234, sb.MaxCapacity);
  61. }
  62. [Test]
  63. public void TestConstructor4()
  64. {
  65. // check for exception in ctor that specifies the capacity & maxCapacity
  66. try {
  67. sb = new StringBuilder(9999, 15);
  68. }
  69. catch (ArgumentOutOfRangeException) {
  70. return;
  71. }
  72. // if we didn't catch an exception, then we have a problem Houston.
  73. Assert.Fail("Capacity exceeds MaxCapacity");
  74. }
  75. [Test]
  76. public void TestConstructor5() {
  77. String someString = null;
  78. sb = new StringBuilder(someString);
  79. Assert.AreEqual(String.Empty, sb.ToString(), "Should be empty string");
  80. }
  81. [Test]
  82. public void TestConstructor6() {
  83. // check for exception in ctor that prevents startIndex less than zero
  84. try {
  85. String someString = "someString";
  86. sb = new StringBuilder(someString, -1, 3, 18);
  87. }
  88. catch (ArgumentOutOfRangeException) {
  89. return;
  90. }
  91. // if we didn't catch an exception, then we have a problem Houston.
  92. Assert.Fail("StartIndex not allowed to be less than zero.");
  93. }
  94. [Test]
  95. public void TestConstructor7() {
  96. // check for exception in ctor that prevents length less than zero
  97. try {
  98. String someString = "someString";
  99. sb = new StringBuilder(someString, 2, -222, 18);
  100. }
  101. catch (ArgumentOutOfRangeException) {
  102. return;
  103. }
  104. // if we didn't catch an exception, then we have a problem Houston.
  105. Assert.Fail("Length not allowed to be less than zero.");
  106. }
  107. [Test]
  108. public void TestConstructor8() {
  109. // check for exception in ctor that ensures substring is contained in given string
  110. // check that startIndex is not too big
  111. try {
  112. String someString = "someString";
  113. sb = new StringBuilder(someString, 10000, 4, 18);
  114. }
  115. catch (ArgumentOutOfRangeException) {
  116. return;
  117. }
  118. // if we didn't catch an exception, then we have a problem Houston.
  119. Assert.Fail ("StartIndex and length must refer to a location within the string.");
  120. }
  121. [Test]
  122. public void TestConstructor9() {
  123. // check for exception in ctor that ensures substring is contained in given string
  124. // check that length doesn't go beyond end of string
  125. try {
  126. String someString = "someString";
  127. sb = new StringBuilder(someString, 4, 4000, 18);
  128. }
  129. catch (ArgumentOutOfRangeException) {
  130. return;
  131. }
  132. // if we didn't catch an exception, then we have a problem Houston.
  133. Assert.Fail ("StartIndex and length must refer to a location within the string.");
  134. }
  135. [Test]
  136. public void TestConstructor10() {
  137. // check that substring is taken properly and made into a StringBuilder
  138. String someString = "someString";
  139. sb = new StringBuilder(someString, 4, 6, 18);
  140. string expected = "String";
  141. Assert.AreEqual( expected, sb.ToString());
  142. }
  143. [Test]
  144. [ExpectedException(typeof(ArgumentOutOfRangeException))]
  145. public void TestConstructor11 () {
  146. new StringBuilder (-1);
  147. }
  148. [Test]
  149. public void TestAppend() {
  150. StringBuilder sb = new StringBuilder( "Foo" );
  151. sb.Append( "Two" );
  152. string expected = "FooTwo";
  153. Assert.AreEqual( expected, sb.ToString() );
  154. }
  155. [Test]
  156. public void TestInsert() {
  157. StringBuilder sb = new StringBuilder();
  158. Assert.AreEqual( String.Empty, sb.ToString() );
  159. /* Test empty StringBuilder conforms to spec */
  160. sb.Insert( 0, "Foo" ); /* Test insert at start of empty string */
  161. Assert.AreEqual( "Foo", sb.ToString() );
  162. sb.Insert( 1, "!!" ); /* Test insert not at start of string */
  163. Assert.AreEqual( "F!!oo", sb.ToString() );
  164. sb.Insert( 5, ".." ); /* Test insert at end of string */
  165. Assert.AreEqual( "F!!oo..", sb.ToString() );
  166. sb.Insert( 0, 1234 ); /* Test insert of a number (at start of string) */
  167. // FIX: Why does this test fail?
  168. //Assert.AreEqual( "1234F!!oo..", sb.ToString() );
  169. sb.Insert( 5, 1.5 ); /* Test insert of a decimal (and end of string) */
  170. // FIX: Why does this test fail?
  171. //Assert.AreEqual( "1234F1.5!!oo..", sb.ToString() );
  172. sb.Insert( 4, 'A' ); /* Test char insert in middle of string */
  173. // FIX: Why does this test fail?
  174. //Assert.AreEqual( "1234AF1.5!!oo..", sb.ToString() );
  175. }
  176. [Test]
  177. public void TestReplace() {
  178. StringBuilder sb = new StringBuilder( "Foobarbaz" );
  179. sb.Replace( "bar", "!!!" ); /* Test same length replace in middle of string */
  180. Assert.AreEqual( "Foo!!!baz", sb.ToString() );
  181. sb.Replace( "Foo", "ABcD" ); /* Test longer replace at start of string */
  182. Assert.AreEqual( "ABcD!!!baz", sb.ToString() );
  183. sb.Replace( "baz", "00" ); /* Test shorter replace at end of string */
  184. Assert.AreEqual( "ABcD!!!00", sb.ToString() );
  185. sb.Replace( sb.ToString(), null ); /* Test string clear as in spec */
  186. Assert.AreEqual( String.Empty, sb.ToString() );
  187. /* | 10 20 30
  188. /* |0123456789012345678901234567890| */
  189. sb.Append( "abc this is testing abc the abc abc partial replace abc" );
  190. sb.Replace( "abc", "!!!", 0, 31 ); /* Partial replace at start of string */
  191. Assert.AreEqual( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
  192. sb.Replace( "testing", "", 0, 15 ); /* Test replace across boundary */
  193. Assert.AreEqual( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
  194. sb.Replace( "!!!", "" ); /* Test replace with empty string */
  195. Assert.AreEqual(sb.ToString() , " this is testing the abc partial replace abc");
  196. }
  197. [Test]
  198. public void TestAppendFormat() {
  199. }
  200. [Test]
  201. public void MoreReplace ()
  202. {
  203. StringBuilder sb = new StringBuilder ();
  204. sb.Append ("First");
  205. sb.Append ("Second");
  206. sb.Append ("Third");
  207. sb.Replace ("Second", "Gone", 2, sb.Length-2);
  208. Assert.AreEqual ("FirstGoneThird", sb.ToString (), "#01");
  209. sb.Length = 0;
  210. sb.Append ("This, is, a, list");
  211. sb.Replace (",", "comma-separated", 11, sb.Length-11);
  212. Assert.AreEqual ("This, is, acomma-separated list", sb.ToString (), "#02");
  213. }
  214. [Test]
  215. public void Insert0 ()
  216. {
  217. StringBuilder sb = new StringBuilder();
  218. sb.Append("testtesttest");
  219. sb.Insert(0, '^');
  220. Assert.AreEqual ("^testtesttest", sb.ToString (), "#01");
  221. }
  222. [Test]
  223. public void AppendToEmpty ()
  224. {
  225. StringBuilder sb = new StringBuilder();
  226. char [] ca = new char [] { 'c' };
  227. sb.Append (ca);
  228. Assert.AreEqual ("c", sb.ToString (), "#01");
  229. }
  230. [Test]
  231. public void TestRemove ()
  232. {
  233. StringBuilder b = new StringBuilder ();
  234. b.Append ("Hello, I am a StringBuilder");
  235. b.Remove (0, 7); // Should remove "Hello, "
  236. Assert.AreEqual ("I am a StringBuilder", b.ToString (), "#01");
  237. }
  238. [Test]
  239. public void Insert1 ()
  240. {
  241. StringBuilder sb = new StringBuilder();
  242. sb.Insert(0, "aa");
  243. Assert.AreEqual ("aa", sb.ToString (), "#01");
  244. char [] charArr = new char [] { 'b', 'c', 'd' };
  245. sb.Insert(1, charArr, 1, 1);
  246. Assert.AreEqual ("aca", sb.ToString (), "#02");
  247. sb.Insert (1, null, 0, 0);
  248. Assert.AreEqual ("aca", sb.ToString (), "#03");
  249. try {
  250. sb.Insert (1, null, 1, 1);
  251. Assert.Fail ("#04: Value must not be null if startIndex and charCount > 0");
  252. } catch (ArgumentNullException) {}
  253. }
  254. [Test]
  255. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  256. public void Constructor_StartIndexOverflow ()
  257. {
  258. new StringBuilder ("Mono", Int32.MaxValue, 1, 0);
  259. }
  260. [Test]
  261. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  262. public void Constructor_LengthOverflow ()
  263. {
  264. new StringBuilder ("Mono", 1, Int32.MaxValue, 0);
  265. }
  266. [Test]
  267. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  268. public void ToString_StartIndexOverflow ()
  269. {
  270. StringBuilder sb = new StringBuilder ("Mono");
  271. sb.ToString (Int32.MaxValue, 1);
  272. }
  273. [Test]
  274. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  275. public void ToString_LengthOverflow ()
  276. {
  277. StringBuilder sb = new StringBuilder ("Mono");
  278. sb.ToString (1, Int32.MaxValue);
  279. }
  280. [Test]
  281. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  282. public void Remove_StartIndexOverflow ()
  283. {
  284. StringBuilder sb = new StringBuilder ("Mono");
  285. sb.Remove (Int32.MaxValue, 1);
  286. }
  287. [Test]
  288. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  289. public void Remove_LengthOverflow ()
  290. {
  291. StringBuilder sb = new StringBuilder ("Mono");
  292. sb.Remove (1, Int32.MaxValue);
  293. }
  294. [Test]
  295. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  296. public void ReplaceChar_StartIndexOverflow ()
  297. {
  298. StringBuilder sb = new StringBuilder ("Mono");
  299. sb.Replace ('o', '0', Int32.MaxValue, 1);
  300. }
  301. [Test]
  302. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  303. public void ReplaceChar_CountOverflow ()
  304. {
  305. StringBuilder sb = new StringBuilder ("Mono");
  306. sb.Replace ('0', '0', 1, Int32.MaxValue);
  307. }
  308. [Test]
  309. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  310. public void ReplaceString_StartIndexOverflow ()
  311. {
  312. StringBuilder sb = new StringBuilder ("Mono");
  313. sb.Replace ("o", "0", Int32.MaxValue, 1);
  314. }
  315. [Test]
  316. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  317. public void ReplaceString_CountOverflow ()
  318. {
  319. StringBuilder sb = new StringBuilder ("Mono");
  320. sb.Replace ("o", "0", 1, Int32.MaxValue);
  321. }
  322. [Test]
  323. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  324. public void AppendCharArray_StartIndexOverflow ()
  325. {
  326. StringBuilder sb = new StringBuilder ("Mono");
  327. sb.Append (new char[2], Int32.MaxValue, 1);
  328. }
  329. [Test]
  330. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  331. public void AppendCharArray_CharCountOverflow ()
  332. {
  333. StringBuilder sb = new StringBuilder ("Mono");
  334. sb.Append (new char[2], 1, Int32.MaxValue);
  335. }
  336. [Test]
  337. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  338. public void AppendString_StartIndexOverflow ()
  339. {
  340. StringBuilder sb = new StringBuilder ("Mono");
  341. sb.Append ("!", Int32.MaxValue, 1);
  342. }
  343. [Test]
  344. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  345. public void AppendString_CountOverflow ()
  346. {
  347. StringBuilder sb = new StringBuilder ("Mono");
  348. sb.Append ("!", 1, Int32.MaxValue);
  349. }
  350. [Test]
  351. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  352. public void InsertCharArray_StartIndexOverflow ()
  353. {
  354. StringBuilder sb = new StringBuilder ("Mono");
  355. sb.Insert (0, new char[2], Int32.MaxValue, 1);
  356. }
  357. [Test]
  358. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  359. public void InsertCharArray_CharCountOverflow ()
  360. {
  361. StringBuilder sb = new StringBuilder ("Mono");
  362. sb.Insert (0, new char[2], 1, Int32.MaxValue);
  363. }
  364. [Test]
  365. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  366. public void MaxCapacity_Overflow1 ()
  367. {
  368. StringBuilder sb = new StringBuilder (2, 3);
  369. sb.Append ("Mono");
  370. }
  371. [Test]
  372. public void MaxCapacity_Overflow2 ()
  373. {
  374. StringBuilder sb = new StringBuilder (2, 3);
  375. try {
  376. sb.Append ("Mono");
  377. } catch (ArgumentOutOfRangeException) {
  378. }
  379. Assert.AreEqual (2, sb.Capacity);
  380. Assert.AreEqual (3, sb.MaxCapacity);
  381. }
  382. [Test]
  383. #if ONLY_1_1
  384. [ExpectedException (typeof (ArgumentOutOfRangeException))]
  385. [Category ("NotWorking")] // Mono follows 2.0 behaviour in this case
  386. #endif
  387. public void MaxCapacity_Overflow3 ()
  388. {
  389. //
  390. // When the capacity (4) gets doubled, it is greater than the
  391. // max capacity. This makes sure that before throwing an exception
  392. // we first attempt to go for a smaller size.
  393. //
  394. new StringBuilder(4, 7).Append ("foo").Append ("bar");
  395. new StringBuilder(4, 6).Append ("foo").Append ("bar");
  396. // this throws ArgumentOutOfRangeException on MS 1.1 SP1
  397. }
  398. [Test]
  399. public void CapacityFromString ()
  400. {
  401. StringBuilder sb = new StringBuilder ("hola").Append ("lala");
  402. Assert.AreEqual ("holalala", sb.ToString (), "#01");
  403. }
  404. [Test]
  405. public void ReplaceWithLargerString ()
  406. {
  407. StringBuilder sb = new StringBuilder ("ABCDE");
  408. Assert.AreEqual ("ABCDE", sb.ToString (), "#1");
  409. sb.Replace ("ABC", "abcaa", 0, 3);
  410. Assert.AreEqual ("abcaaDE", sb.ToString (), "#2");
  411. }
  412. [Test]
  413. public void MaxCapacity_Overflow4 ()
  414. {
  415. StringBuilder sb = new StringBuilder (2, 3);
  416. Assert.AreEqual (2, sb.Capacity);
  417. Assert.AreEqual (3, sb.MaxCapacity);
  418. try {
  419. sb.Length = 4;
  420. Assert.Fail ("#01");
  421. } catch (ArgumentOutOfRangeException) {
  422. }
  423. try {
  424. sb.EnsureCapacity (5);
  425. Assert.Fail ("#02");
  426. } catch (ArgumentOutOfRangeException) {
  427. }
  428. }
  429. [Test]
  430. public void NullInCtor ()
  431. {
  432. StringBuilder sb = null;
  433. try {
  434. sb = new StringBuilder (null, 10);
  435. } catch (Exception e) {
  436. Assert.Fail ("Should not throw #01");
  437. }
  438. Assert.IsTrue (sb.Length == 0);
  439. }
  440. [Test]
  441. public void SetLength ()
  442. {
  443. StringBuilder sb = new StringBuilder ("Text");
  444. Assert.AreEqual (4, sb.Length, "#1");
  445. Assert.AreEqual ("Text", sb.ToString (), "#2");
  446. sb.Length = 8;
  447. Assert.AreEqual (8, sb.Length, "#3");
  448. Assert.AreEqual ("Text\0\0\0\0", sb.ToString (), "#4");
  449. }
  450. #if NET_4_0 || MOONLIGHT || MOBILE
  451. [Test]
  452. public void ClearMethod () {
  453. StringBuilder sb = new StringBuilder ("Text");
  454. sb.Clear ();
  455. Assert.AreEqual (0, sb.Length, "#1");
  456. Assert.AreEqual (String.Empty, sb.ToString (), "#2");
  457. }
  458. #endif
  459. }
  460. }