Merge pull request #1870 from saper/langinfo_h
[mono.git] / mcs / class / corlib / Test / System.Text / StringBuilderTest.cs
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 (marcins@zipworld.com.au)
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
23 using NUnit.Framework;
24 using System.Text;
25 using System;
26
27 namespace MonoTests.System.Text {
28
29         [TestFixture]
30         public class StringBuilderTest  {
31
32                 private StringBuilder sb;
33
34                 [Test]
35                 public void TestConstructor1() 
36                 {
37                         // check the parameterless ctor
38                         sb = new StringBuilder();
39                         Assert.AreEqual(String.Empty, sb.ToString());
40                         Assert.AreEqual(0, sb.Length);
41                         Assert.AreEqual(16, sb.Capacity);
42                 }
43
44                 [Test]
45                 public void TestConstructor2() 
46                 {
47                         // check ctor that specifies the capacity
48                         sb = new StringBuilder(10);
49                         Assert.AreEqual(String.Empty, sb.ToString());
50                         Assert.AreEqual(0, sb.Length);
51                         // check that capacity is not less than default
52                         Assert.AreEqual(10, sb.Capacity);
53
54                         sb = new StringBuilder(42);
55                         Assert.AreEqual(String.Empty, sb.ToString());
56                         Assert.AreEqual(0, sb.Length);
57                         // check that capacity is set
58                         Assert.AreEqual(42, sb.Capacity);
59                 }
60
61                 [Test]          
62                 public void TestConstructor3() {
63                         // check ctor that specifies the capacity & maxCapacity
64                         sb = new StringBuilder(444, 1234);
65                         Assert.AreEqual(String.Empty, sb.ToString());
66                         Assert.AreEqual(0, sb.Length);
67                         Assert.AreEqual(444, sb.Capacity);
68                         Assert.AreEqual(1234, sb.MaxCapacity);
69                 }
70
71                 [Test]
72                 public void TestConstructor4() 
73                 {
74                         // check for exception in ctor that specifies the capacity & maxCapacity
75                         try {
76                                 sb = new StringBuilder(9999, 15);
77                         }
78                         catch (ArgumentOutOfRangeException) {
79                                 return;
80                         }
81                         // if we didn't catch an exception, then we have a problem Houston.
82                         Assert.Fail("Capacity exceeds MaxCapacity");
83                 }
84
85                 [Test]
86         public void TestConstructor5() {
87                 String someString = null;
88                 sb = new StringBuilder(someString);
89                 Assert.AreEqual(String.Empty, sb.ToString(), "Should be empty string");
90         }
91
92                 [Test]
93         public void TestConstructor6() {
94                 // check for exception in ctor that prevents startIndex less than zero
95                 try {
96                         String someString = "someString";
97                         sb = new StringBuilder(someString, -1, 3, 18);
98                 }
99                 catch (ArgumentOutOfRangeException) {
100                         return;
101                 }
102                 // if we didn't catch an exception, then we have a problem Houston.
103                 Assert.Fail("StartIndex not allowed to be less than zero.");
104         }
105
106                 [Test]
107         public void TestConstructor7() {
108                 // check for exception in ctor that prevents length less than zero
109                 try {
110                         String someString = "someString";
111                         sb = new StringBuilder(someString, 2, -222, 18);
112                 }
113                 catch (ArgumentOutOfRangeException) {
114                         return;
115                 }
116                 // if we didn't catch an exception, then we have a problem Houston.
117                 Assert.Fail("Length not allowed to be less than zero.");
118         }
119
120                 [Test]
121         public void TestConstructor8() {
122                 // check for exception in ctor that ensures substring is contained in given string
123                 // check that startIndex is not too big
124                 try {
125                         String someString = "someString";
126                         sb = new StringBuilder(someString, 10000, 4, 18);
127                 }
128                 catch (ArgumentOutOfRangeException) {
129                         return;
130                 }
131                 // if we didn't catch an exception, then we have a problem Houston.
132                 Assert.Fail ("StartIndex and length must refer to a location within the string.");
133         }
134
135                 [Test]
136         public void TestConstructor9() {
137                 // check for exception in ctor that ensures substring is contained in given string
138                 // check that length doesn't go beyond end of string
139                 try {
140                         String someString = "someString";
141                         sb = new StringBuilder(someString, 4, 4000, 18);
142                 }
143                 catch (ArgumentOutOfRangeException) {
144                         return;
145                 }
146                 // if we didn't catch an exception, then we have a problem Houston.
147                 Assert.Fail ("StartIndex and length must refer to a location within the string.");
148         }
149
150                 [Test]
151         public void TestConstructor10() {
152                 // check that substring is taken properly and made into a StringBuilder
153                 String someString = "someString";
154                 sb = new StringBuilder(someString, 4, 6, 18);
155                 string expected = "String";
156                 Assert.AreEqual( expected, sb.ToString());
157         }
158
159                 [Test]
160         [ExpectedException(typeof(ArgumentOutOfRangeException))]
161         public void TestConstructor11 () {
162                 new StringBuilder (-1);
163         }
164
165                 [Test]          
166         public void TestAppend() {
167                 StringBuilder sb = new StringBuilder( "Foo" );
168                 sb.Append( "Two" );
169                 string expected = "FooTwo";
170                 Assert.AreEqual( expected, sb.ToString() );
171         }
172
173                 [Test]
174         public void TestInsert() {
175                 StringBuilder sb = new StringBuilder();
176
177                 Assert.AreEqual( String.Empty, sb.ToString() ); 
178                         /* Test empty StringBuilder conforms to spec */
179
180                 sb.Insert( 0, "Foo" ); /* Test insert at start of empty string */
181
182                 Assert.AreEqual( "Foo", sb.ToString() );
183
184                 sb.Insert( 1, "!!" ); /* Test insert not at start of string */
185
186                 Assert.AreEqual( "F!!oo", sb.ToString() );
187
188                 sb.Insert( 5, ".." ); /* Test insert at end of string */
189
190                 Assert.AreEqual( "F!!oo..", sb.ToString() );
191         
192                 sb.Insert( 0, 1234 ); /* Test insert of a number (at start of string) */
193                 
194                                 // FIX: Why does this test fail?
195                 //Assert.AreEqual( "1234F!!oo..", sb.ToString() );
196                 
197                 sb.Insert( 5, 1.5 ); /* Test insert of a decimal (and end of string) */
198                 
199                                 // FIX: Why does this test fail?
200                                 //Assert.AreEqual( "1234F1.5!!oo..", sb.ToString() );
201
202                 sb.Insert( 4, 'A' ); /* Test char insert in middle of string */
203
204                                 // FIX: Why does this test fail?
205                                 //Assert.AreEqual( "1234AF1.5!!oo..", sb.ToString() );
206
207         }
208
209                 [Test]
210         public void TestReplace() {
211                 StringBuilder sb = new StringBuilder( "Foobarbaz" );
212
213                 sb.Replace( "bar", "!!!" );             /* Test same length replace in middle of string */
214                 
215                 Assert.AreEqual( "Foo!!!baz", sb.ToString() );
216
217                 sb.Replace( "Foo", "ABcD" );            /* Test longer replace at start of string */
218
219                 Assert.AreEqual( "ABcD!!!baz", sb.ToString() );
220
221                 sb.Replace( "baz", "00" );              /* Test shorter replace at end of string */
222                         
223                 Assert.AreEqual( "ABcD!!!00", sb.ToString() );
224
225                 sb.Replace( sb.ToString(), null );      /* Test string clear as in spec */
226
227                 Assert.AreEqual( String.Empty, sb.ToString() );
228
229                 /*           |         10        20        30
230                 /*         |0123456789012345678901234567890| */
231                 sb.Append( "abc this is testing abc the abc abc partial replace abc" );
232
233                 sb.Replace( "abc", "!!!", 0, 31 ); /* Partial replace at start of string */
234
235                 Assert.AreEqual( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
236
237                 sb.Replace( "testing", "", 0, 15 ); /* Test replace across boundary */
238
239                 Assert.AreEqual( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
240
241                 sb.Replace( "!!!", "" ); /* Test replace with empty string */
242
243                 Assert.AreEqual(sb.ToString() , " this is testing  the  abc partial replace abc");
244         }
245
246                 [Test]
247         public void TestAppendFormat() {
248         }
249
250         [Test]
251         public void MoreReplace ()
252         {
253                 StringBuilder sb = new StringBuilder ();
254                 sb.Append ("First");
255                 sb.Append ("Second");
256                 sb.Append ("Third");
257                 sb.Replace ("Second", "Gone", 2, sb.Length-2);
258                 Assert.AreEqual ("FirstGoneThird", sb.ToString (), "#01");
259
260                 sb.Length = 0;
261                 sb.Append ("This, is, a, list");
262                 sb.Replace (",", "comma-separated", 11, sb.Length-11);
263                 Assert.AreEqual ("This, is, acomma-separated list", sb.ToString (), "#02");
264         }
265
266         [Test]
267         public void Insert0 ()
268         {
269                 StringBuilder sb = new StringBuilder();
270                 sb.Append("testtesttest");
271                 sb.Insert(0, '^');
272                 Assert.AreEqual ("^testtesttest", sb.ToString (), "#01");
273         }
274
275         [Test]
276         public void AppendToEmpty ()
277         {
278                 StringBuilder sb = new StringBuilder();
279                 char [] ca = new char [] { 'c' };
280                 sb.Append (ca);
281                 Assert.AreEqual ("c", sb.ToString (), "#01");
282         }
283
284
285         [Test]
286         public void TestRemove ()
287         {
288                 StringBuilder b = new StringBuilder ();
289                 b.Append ("Hello, I am a StringBuilder");
290                 b.Remove (0, 7);  // Should remove "Hello, "
291                 Assert.AreEqual ("I am a StringBuilder", b.ToString (), "#01");
292         }
293
294         [Test]
295         public void Insert1 ()
296         {
297                 StringBuilder sb = new StringBuilder();
298                 sb.Insert(0, "aa");
299                 Assert.AreEqual ("aa", sb.ToString (), "#01");
300
301                 char [] charArr = new char [] { 'b', 'c', 'd' };
302                 sb.Insert(1, charArr, 1, 1);
303                 Assert.AreEqual ("aca", sb.ToString (), "#02");
304
305                 sb.Insert (1, null, 0, 0);
306                 Assert.AreEqual ("aca", sb.ToString (), "#03");
307                 
308                 try {
309                         sb.Insert (1, null, 1, 1);
310                         Assert.Fail ("#04: Value must not be null if startIndex and charCount > 0");
311                 } catch (ArgumentNullException) {}
312         }
313
314         [Test]
315         [ExpectedException (typeof (ArgumentOutOfRangeException))]
316         public void Constructor_StartIndexOverflow () 
317         {
318                 new StringBuilder ("Mono", Int32.MaxValue, 1, 0);
319         }
320
321         [Test]
322         [ExpectedException (typeof (ArgumentOutOfRangeException))]
323         public void Constructor_LengthOverflow () 
324         {
325                 new StringBuilder ("Mono", 1, Int32.MaxValue, 0);
326         }
327
328         [Test]
329         [ExpectedException (typeof (ArgumentOutOfRangeException))]
330         public void ToString_StartIndexOverflow () 
331         {
332                 StringBuilder sb = new StringBuilder ("Mono");
333                 sb.ToString (Int32.MaxValue, 1);
334         }
335
336         [Test]
337         [ExpectedException (typeof (ArgumentOutOfRangeException))]
338         public void ToString_LengthOverflow () 
339         {
340                 StringBuilder sb = new StringBuilder ("Mono");
341                 sb.ToString (1, Int32.MaxValue);
342         }
343
344         [Test]
345         [ExpectedException (typeof (ArgumentOutOfRangeException))]
346         public void Remove_StartIndexOverflow () 
347         {
348                 StringBuilder sb = new StringBuilder ("Mono");
349                 sb.Remove (Int32.MaxValue, 1);
350         }
351
352         [Test]
353         [ExpectedException (typeof (ArgumentOutOfRangeException))]
354         public void Remove_LengthOverflow () 
355         {
356                 StringBuilder sb = new StringBuilder ("Mono");
357                 sb.Remove (1, Int32.MaxValue);
358         }
359
360         [Test]
361         [ExpectedException (typeof (ArgumentOutOfRangeException))]
362         public void ReplaceChar_StartIndexOverflow () 
363         {
364                 StringBuilder sb = new StringBuilder ("Mono");
365                 sb.Replace ('o', '0', Int32.MaxValue, 1);
366         }
367
368         [Test]
369         [ExpectedException (typeof (ArgumentOutOfRangeException))]
370         public void ReplaceChar_CountOverflow () 
371         {
372                 StringBuilder sb = new StringBuilder ("Mono");
373                 sb.Replace ('0', '0', 1, Int32.MaxValue);
374         }
375
376         [Test]
377         [ExpectedException (typeof (ArgumentOutOfRangeException))]
378         public void ReplaceString_StartIndexOverflow () 
379         {
380                 StringBuilder sb = new StringBuilder ("Mono");
381                 sb.Replace ("o", "0", Int32.MaxValue, 1);
382         }
383
384         [Test]
385         [ExpectedException (typeof (ArgumentOutOfRangeException))]
386         public void ReplaceString_CountOverflow () 
387         {
388                 StringBuilder sb = new StringBuilder ("Mono");
389                 sb.Replace ("o", "0", 1, Int32.MaxValue);
390         }
391
392         [Test]
393         [ExpectedException (typeof (ArgumentOutOfRangeException))]
394         public void AppendCharArray_StartIndexOverflow () 
395         {
396                 StringBuilder sb = new StringBuilder ("Mono");
397                 sb.Append (new char[2], Int32.MaxValue, 1);
398         }
399
400         [Test]
401         [ExpectedException (typeof (ArgumentOutOfRangeException))]
402         public void AppendCharArray_CharCountOverflow () 
403         {
404                 StringBuilder sb = new StringBuilder ("Mono");
405                 sb.Append (new char[2], 1, Int32.MaxValue);
406         }
407
408         [Test]
409         [ExpectedException (typeof (ArgumentOutOfRangeException))]
410         public void AppendString_StartIndexOverflow () 
411         {
412                 StringBuilder sb = new StringBuilder ("Mono");
413                 sb.Append ("!", Int32.MaxValue, 1);
414         }
415
416         [Test]
417         [ExpectedException (typeof (ArgumentOutOfRangeException))]
418         public void AppendString_CountOverflow () 
419         {
420                 StringBuilder sb = new StringBuilder ("Mono");
421                 sb.Append ("!", 1, Int32.MaxValue);
422         }
423
424         [Test]
425         [ExpectedException (typeof (ArgumentOutOfRangeException))]
426         public void InsertCharArray_StartIndexOverflow () 
427         {
428                 StringBuilder sb = new StringBuilder ("Mono");
429                 sb.Insert (0, new char[2], Int32.MaxValue, 1);
430         }
431
432         [Test]
433         [ExpectedException (typeof (ArgumentOutOfRangeException))]
434         public void InsertCharArray_CharCountOverflow () 
435         {
436                 StringBuilder sb = new StringBuilder ("Mono");
437                 sb.Insert (0, new char[2], 1, Int32.MaxValue);
438         }
439
440         [Test]
441         [ExpectedException (typeof (ArgumentOutOfRangeException))]
442         public void MaxCapacity_Overflow1 ()
443         {
444                 StringBuilder sb = new StringBuilder (2, 3);
445                 sb.Append ("Mono");
446         }
447
448         [Test]
449         public void MaxCapacity_Overflow2 ()
450         {
451                 StringBuilder sb = new StringBuilder (2, 3);
452                 try {
453                         sb.Append ("Mono");
454                 } catch (ArgumentOutOfRangeException) {
455                 }
456
457                 Assert.AreEqual (2, sb.Capacity);
458                 Assert.AreEqual (3, sb.MaxCapacity);
459         }
460         
461         [Test]
462         public void MaxCapacity_Overflow3 ()
463         {
464                 //
465                 // When the capacity (4) gets doubled, it is greater than the
466                 // max capacity. This makes sure that before throwing an exception
467                 // we first attempt to go for a smaller size.
468                 //
469                 new StringBuilder(4, 7).Append ("foo").Append ("bar");
470                 new StringBuilder(4, 6).Append ("foo").Append ("bar");
471                 // this throws ArgumentOutOfRangeException on MS 1.1 SP1
472         }
473
474         [Test]
475         public void CapacityFromString ()
476         {
477                 StringBuilder sb = new StringBuilder ("hola").Append ("lala");
478                 Assert.AreEqual ("holalala", sb.ToString (), "#01");
479         }
480
481         [Test]
482         public void ReplaceWithLargerString ()
483         {
484                 StringBuilder sb = new StringBuilder ("ABCDE");
485                 Assert.AreEqual ("ABCDE", sb.ToString (), "#1");
486                 sb.Replace ("ABC", "abcaa", 0, 3);
487                 Assert.AreEqual ("abcaaDE", sb.ToString (), "#2");
488         }
489
490         [Test]
491         public void MaxCapacity_Overflow4 ()
492         {
493                 StringBuilder sb = new StringBuilder (2, 3);
494                 Assert.AreEqual (2, sb.Capacity);
495                 Assert.AreEqual (3, sb.MaxCapacity);
496                 try {
497                         sb.Length = 4;
498                         Assert.Fail ("#01");
499                 } catch (ArgumentOutOfRangeException) {
500                 }
501
502                 try {
503                         sb.EnsureCapacity (5);
504                         Assert.Fail ("#02");
505                 } catch (ArgumentOutOfRangeException) {
506                 }
507         }
508         
509         [Test]
510         public void NullInCtor ()
511         {
512                 StringBuilder sb = null;
513                 try {
514                         sb = new StringBuilder (null, 10);
515                 } catch (Exception e) {
516                         Assert.Fail ("Should not throw #01");
517                 }
518
519                 Assert.IsTrue (sb.Length == 0);
520         }
521
522         [Test]
523         public void SetLength ()
524         {
525                 StringBuilder sb = new StringBuilder ("Text");
526                 Assert.AreEqual (4, sb.Length, "#1");
527                 Assert.AreEqual ("Text", sb.ToString (), "#2");
528                 sb.Length = 8;
529                 Assert.AreEqual (8, sb.Length, "#3");
530                 Assert.AreEqual ("Text\0\0\0\0", sb.ToString (), "#4");
531         }
532
533
534         [Test]
535         public void ClearMethod () {
536                 StringBuilder sb = new StringBuilder ("Text");
537                 sb.Clear ();
538                 Assert.AreEqual (0, sb.Length, "#1");
539                 Assert.AreEqual (String.Empty, sb.ToString (), "#2");
540         }
541
542 }
543
544 }