Initial revision
[mono.git] / mcs / class / corlib / Test / System / StringTest.cs
1 // StringTest.cs - NUnit Test Cases for the System.String class
2 //
3 // Jeffrey Stedfast <fejj@ximian.com>
4 // David Brandt <bucky@keystreams.com>
5 //
6 // (C) Ximian, Inc.  http://www.ximian.com
7 //
8
9 using NUnit.Framework;
10 using System;
11 using System.Globalization;
12
13 namespace MonoTests.System
14 {
15
16 public class StringTest : TestCase
17 {
18         public StringTest() : base ("MonoTests.System.StringTest testcase") {}\r
19         public StringTest (string name) : base (name) {}
20
21         protected override void SetUp ()
22         {
23         }
24
25         public static ITest Suite {
26                 get {
27                         return new TestSuite (typeof (StringTest));
28                 }
29         }
30
31         public void TestLength ()
32         {
33                 string str = "test string";
34
35                 AssertEquals("wrong length", 11, str.Length);
36         }
37
38         public void TestCompare ()
39         {
40                 string lesser = "abc";
41                 string medium = "abcd";
42                 string greater = "xyz";
43                 string caps = "ABC";
44
45                 AssertEquals(0, String.Compare(null, null));
46                 AssertEquals(1, String.Compare(lesser, null));
47
48                 Assert (String.Compare (lesser, greater) < 0);
49                 Assert (String.Compare (greater, lesser) > 0);
50                 Assert (String.Compare (lesser, lesser) == 0);
51                 Assert (String.Compare (lesser, medium) < 0);
52
53                 Assert (String.Compare (lesser, caps, true) == 0);
54                 Assert (String.Compare (lesser, caps, false) != 0);
55                 AssertEquals ("A01", String.Compare ("a", "b"), -1);\r
56                 AssertEquals ("A02", String.Compare ("b", "a"), 1);\r
57                 AssertEquals ("A03", String.Compare ("A", "a"), 1);\r
58                 AssertEquals ("A04", String.Compare ("a", "A"), -1);\r
59 \r
60
61                 // TODO - test with CultureInfo
62
63                 string needle = "ab";
64                 string haystack = "abbcbacab";
65                 AssertEquals("basic substring check #1", 0, \r
66                              String.Compare(needle, 0, haystack, 0, 2));
67                 AssertEquals("basic substring check #2", -1,\r
68                              String.Compare(needle, 0, haystack, 0, 3));
69                 AssertEquals("basic substring check #3", 0, \r
70                              String.Compare("ab", 0, "ab", 0, 2));\r
71                 AssertEquals("basic substring check #4", 0, \r
72                              String.Compare("ab", 0, "ab", 0, 3));\r
73                 AssertEquals("basic substring check #5", 0, \r
74                              String.Compare("abc", 0, "ab", 0, 2));\r
75                 AssertEquals("basic substring check #6", 1, \r
76                              String.Compare("abc", 0, "ab", 0, 5));\r
77                 AssertEquals("basic substring check #7", -1, \r
78                              String.Compare("ab", 0, "abc", 0, 5));\r
79 \r
80                 for (int i = 1; i <= (haystack.Length - needle.Length); i++) {
81                         if (i != 7) {
82                                 Assert("loop substring check #1/" + i, String.Compare(needle, 0, haystack, i, 2) != 0);\r
83                                 Assert("loop substring check #2/" + i, String.Compare(needle, 0, haystack, i, 3) != 0);\r
84                         } else {
85                                 AssertEquals("loop substring check #3/" + i, 0, String.Compare(needle, 0, haystack, i, 2));\r
86                                 AssertEquals("loop substring check #4/" + i, 0, String.Compare(needle, 0, haystack, i, 3));\r
87                         }
88                 }
89
90                 needle = "AB";
91                 AssertEquals("basic substring check #8", 0, \r
92                              String.Compare(needle, 0, haystack, 0, 2, true));
93                 AssertEquals("basic substring check #9", 1, \r
94                              String.Compare(needle, 0, haystack, 0, 2, false));
95                 for (int i = 1; i <= (haystack.Length - needle.Length); i++) {
96                         if (i != 7) {
97                                 Assert("loop substring check #5/" + i, String.Compare(needle, 0, haystack, i, 2, true) != 0);\r
98                                 Assert("loop substring check #6/" + i, String.Compare(needle, 0, haystack, i, 2, false) != 0);\r
99                         } else {
100                                 AssertEquals("loop substring check #7/" + i, 0, String.Compare(needle, 0, haystack, i, 2, true));\r
101                                 AssertEquals("loop substring check #8/" + i, 1, String.Compare(needle, 0, haystack, i, 2, false));\r
102                         }
103                 }
104
105                 // TODO - extended format call with CultureInfo
106         }
107
108         public void TestCompareOrdinal ()
109         {
110                 string lesser = "abc";
111                 string medium = "abcd";
112                 string greater = "xyz";
113
114                 AssertEquals(0, String.CompareOrdinal(null, null));
115                 AssertEquals(1, String.CompareOrdinal(lesser, null));
116
117                 Assert (String.CompareOrdinal (lesser, greater) < 0);
118                 Assert (String.CompareOrdinal (greater, lesser) > 0);
119                 Assert (String.CompareOrdinal (lesser, lesser) == 0);
120                 Assert (String.CompareOrdinal (lesser, medium) < 0);
121
122                 string needle = "ab";
123                 string haystack = "abbcbacab";
124                 AssertEquals("basic substring check", 0, 
125                              String.CompareOrdinal(needle, 0, haystack, 0, 2));
126                 AssertEquals("basic substring miss", -1,
127                              String.CompareOrdinal(needle, 0, haystack, 0, 3));
128                 for (int i = 1; i <= (haystack.Length - needle.Length); i++) {
129                         if (i != 7) {
130                                 Assert("loop substring check " + i, String.CompareOrdinal(needle, 0, haystack, i, 2) != 0);
131                                 Assert("loop substring check " + i, String.CompareOrdinal(needle, 0, haystack, i, 3) != 0);
132                         } else {
133                                 AssertEquals("loop substring check " + i, 0, String.CompareOrdinal(needle, 0, haystack, i, 2));
134                                 AssertEquals("loop substring check " + i, 0, String.CompareOrdinal(needle, 0, haystack, i, 3));
135                         }
136                 }
137         }
138
139         public void TestCompareTo ()
140         {
141                 string lower = "abc";
142                 string greater = "xyz";
143                 string lesser = "abc";
144                 
145                 Assert (lower.CompareTo (greater) < 0);
146                 Assert (lower.CompareTo (lower) == 0);
147                 Assert (greater.CompareTo (lesser) > 0);
148         }
149
150         public void TestConcat ()
151         {
152                 string string1 = "string1";
153                 string string2 = "string2";
154                 string concat = "string1string2";
155
156                 Assert (String.Concat (string1, string2) == concat);
157         }
158
159         public void TestCopy()
160         {
161                 string s1 = "original";
162                 string s2 = String.Copy(s1);
163                 AssertEquals("String copy no good", s1, s2);
164
165                 bool errorThrown = false;
166                 try {
167                         string s = String.Copy(null);
168                 } catch (ArgumentNullException) {
169                         errorThrown = true;
170                 }
171                 Assert("null copy shouldn't be good", errorThrown);
172         }
173
174         public void TestCopyTo()
175         {
176                 string s1 = "original";
177
178                 bool errorThrown = false;
179                 try {
180                         s1.CopyTo(0, (char[])null, 0, s1.Length);
181                 } catch (ArgumentNullException) {
182                         errorThrown = true;
183                 }
184                 Assert("null CopyTo shouldn't be good", errorThrown);
185                 
186                 char[] c1 = new char[s1.Length];
187                 string s2 = new String(c1);
188                 Assert("char string not bad to start", !s1.Equals(s2));
189                 for (int i = 0; i < s1.Length; i++) {
190                         s1.CopyTo(i, c1, i, 1);
191                 }
192                 s2 = new String(c1);
193                 AssertEquals("char-by-char copy bad", s1, s2);
194         }
195
196         public void TestEndsWith()
197         {
198                 string s1 = "original";
199                 
200                 bool errorThrown = false;
201                 try {
202                         bool huh = s1.EndsWith(null);
203                 } catch (ArgumentNullException) {
204                         errorThrown = true;
205                 }
206                 Assert("null EndsWith shouldn't be good", errorThrown);
207
208                 Assert("should match", s1.EndsWith("l"));
209                 Assert("should match 2", s1.EndsWith("inal"));
210                 Assert("should fail", !s1.EndsWith("ina"));
211         }
212
213         public void TestEquals()
214         {
215                 string s1 = "original";
216                 string yes = "original";
217                 object y = yes;
218                 string no = "copy";
219
220                 Assert("No match for null", !s1.Equals(null));
221                 Assert("Should match object", s1.Equals(y));
222                 Assert("Should match", s1.Equals(yes));
223                 Assert("Shouldn't match", !s1.Equals(no));
224
225                 Assert("Static nulls should match", String.Equals(null, null));
226                 Assert("Should match", String.Equals(s1, yes));
227                 Assert("Shouldn't match", !String.Equals(s1, no));
228         }
229
230         public void TestFormat ()
231         {
232                 AssertEquals ("Empty format string.", "", String.Format ("", 0));\r
233                 AssertEquals ("Single argument.", "100", String.Format ("{0}", 100));\r
234                 AssertEquals ("Single argument, right justified.", "X   37X", String.Format ("X{0,5}X", 37));\r
235                 AssertEquals ("Single argument, left justified.", "X37   X", String.Format ("X{0,-5}X", 37));\r
236                 AssertEquals ("Two arguments.", "The 3 wise men.", String.Format ("The {0} wise {1}.", 3, "men"));\r
237                 AssertEquals ("Three arguments.", "do re me fa so.", String.Format ("{0} re {1} fa {2}.", "do", "me", "so"));\r
238                 AssertEquals ("Formatted argument.", "###00c0ffee#", String.Format ("###{0:x8}#", 0xc0ffee));\r
239                 AssertEquals ("Formatted argument, right justified.", "#  033#", String.Format ("#{0,5:x3}#", 0x33));\r
240                 AssertEquals ("Formatted argument, left justified.", "#033  #", String.Format ("#{0,-5:x3}#", 0x33));\r
241                 AssertEquals ("Escaped bracket", "typedef struct _MonoObject { ... } MonoObject;", String.Format ("typedef struct _{0} {{ ... }} MonoObject;", "MonoObject"));\r
242                 AssertEquals\r("With Slash", "Could not find file \"a/b\"", String.Format ("Could not find file \"{0}\"", "a/b"));
243                 AssertEquals\r("With BackSlash", "Could not find file \"a\\b\"", String.Format ("Could not find file \"{0}\"", "a\\b"));
244
245                 // TODO test format exceptions
246
247                 // TODO test argument null exceptions
248                 //   This should work, but it doesn't currently.
249                 //   I think I broke the spec...
250                 //bool errorThrown = false;
251                 //try {
252                 //string s = String.Format(null, " ");
253                 //} catch (ArgumentNullException) {
254                 //errorThrown = true;
255                 //}
256                 //Assert("error not thrown 1", errorThrown);
257                 //errorThrown = false;
258                 //try {
259                 //string s = String.Format(null, " ", " ");
260                 //} catch (ArgumentNullException) {
261                 //errorThrown = true;
262                 //}
263                 //Assert("error not thrown 2", errorThrown);
264                 //errorThrown = false;
265                 //try {
266                 //string s = String.Format(" ", null);
267                 //} catch (ArgumentNullException) {
268                 //errorThrown = true;
269                 //}
270                 //Assert("error not thrown 3", errorThrown);
271         }
272
273         public void TestGetEnumerator()
274         {
275                 string s1 = "original";
276                 char[] c1 = new char[s1.Length];
277                 string s2 = new String(c1);
278                 Assert("pre-enumerated string should not match", !s1.Equals(s2));
279                 CharEnumerator en = s1.GetEnumerator();
280                 AssertNotNull("null enumerator", en);
281                 
282                 for (int i = 0; i < s1.Length; i++) {
283                         en.MoveNext();
284                         c1[i] = en.Current;
285                 }
286                 s2 = new String(c1);
287                 AssertEquals("enumerated string should match", s1, s2);
288         }
289
290         public void TestGetHashCode()
291         {
292                 string s1 = "original";
293                 // TODO - weak test, currently.  Just verifies determinicity.
294                 AssertEquals("same string, same hash code", 
295                              s1.GetHashCode(), s1.GetHashCode());
296         }
297
298         public void TestGetType() {
299                 string s1 = "original";
300                 AssertEquals("String type", "System.String", s1.GetType().ToString());
301         }
302
303         public void TestGetTypeCode() {
304                 string s1 = "original";
305                 Assert(s1.GetTypeCode().Equals(TypeCode.String));
306         }
307
308         public void TestIndexOf() {
309                 string s1 = "original";
310
311                 bool errorThrown = false;
312                 try {
313                         int i = s1.IndexOf('q', s1.Length + 1);
314                 } catch (ArgumentOutOfRangeException) {
315                         errorThrown = true;
316                 }
317                 Assert("out of range error for char", errorThrown);
318
319                 errorThrown = false;
320                 try {
321                         int i = s1.IndexOf('q', s1.Length + 1, 1);
322                 } catch (ArgumentOutOfRangeException) {
323                         errorThrown = true;
324                 }
325                 Assert("out of range error for char", errorThrown);
326
327                 errorThrown = false;
328                 try {
329                         int i = s1.IndexOf("huh", s1.Length + 1);
330                 } catch (ArgumentOutOfRangeException) {
331                         errorThrown = true;
332                 }
333                 Assert("out of range for string", errorThrown);
334
335                 errorThrown = false;
336                 try {
337                         int i = s1.IndexOf("huh", s1.Length + 1, 3);
338                 } catch (ArgumentOutOfRangeException) {
339                         errorThrown = true;
340                 }
341                 Assert("out of range for string", errorThrown);
342
343                 errorThrown = false;
344                 try {
345                         int i = s1.IndexOf(null);
346                 } catch (ArgumentNullException) {
347                         errorThrown = true;
348                 }
349                 Assert("null string error", errorThrown);
350
351                 errorThrown = false;
352                 try {
353                         int i = s1.IndexOf(null, 0);
354                 } catch (ArgumentNullException) {
355                         errorThrown = true;
356                 }
357                 Assert("null string error", errorThrown);
358
359                 errorThrown = false;
360                 try {
361                         int i = s1.IndexOf(null, 0, 1);
362                 } catch (ArgumentNullException) {
363                         errorThrown = true;
364                 }
365                 Assert("null string error", errorThrown);
366
367                 AssertEquals("basic char index", 1, s1.IndexOf('r'));
368                 AssertEquals("basic char index", 2, s1.IndexOf('i'));
369                 AssertEquals("basic char index - no", -1, s1.IndexOf('q'));
370                 
371                 AssertEquals("basic string index", 1, s1.IndexOf("rig"));
372                 AssertEquals("basic string index", 2, s1.IndexOf("i"));
373                 AssertEquals("basic string index - no", -1, s1.IndexOf("rag"));
374
375                 AssertEquals("stepped char index", 1, s1.IndexOf('r', 1));
376                 AssertEquals("stepped char index", 2, s1.IndexOf('i', 1));
377                 AssertEquals("stepped char index", 4, s1.IndexOf('i', 3));
378                 AssertEquals("stepped char index", -1, s1.IndexOf('i', 5));
379                 AssertEquals("stepped char index", -1, s1.IndexOf('l', s1.Length));
380
381                 AssertEquals("stepped limited char index", 
382                              1, s1.IndexOf('r', 1, 1));
383                 AssertEquals("stepped limited char index", 
384                              -1, s1.IndexOf('r', 0, 1));
385                 AssertEquals("stepped limited char index", 
386                              2, s1.IndexOf('i', 1, 3));
387                 AssertEquals("stepped limited char index", 
388                              4, s1.IndexOf('i', 3, 3));
389                 AssertEquals("stepped limited char index", 
390                              -1, s1.IndexOf('i', 5, 3));
391
392                 s1 = "original original";
393                 AssertEquals("stepped string index 1",
394                              0, s1.IndexOf("original", 0));
395                 AssertEquals("stepped string index 2", 
396                              9, s1.IndexOf("original", 1));
397                 AssertEquals("stepped string index 3", 
398                              -1, s1.IndexOf("original", 10));
399                 AssertEquals("stepped limited string index 1",
400                              1, s1.IndexOf("rig", 0, 5));
401                 AssertEquals("stepped limited string index 2",
402                              -1, s1.IndexOf("rig", 0, 3));
403                 AssertEquals("stepped limited string index 3",
404                              10, s1.IndexOf("rig", 2, 15));
405                 AssertEquals("stepped limited string index 4",
406                              -1, s1.IndexOf("rig", 2, 3));
407         }
408
409         public void TestIndexOfAny() {
410                 string s1 = "abcdefghijklm";
411
412                 bool errorThrown = false;
413                 try {
414                         int i = s1.IndexOfAny(null);
415                 } catch (ArgumentNullException) {
416                         errorThrown = true;
417                 }
418                 Assert("null char[] error", errorThrown);
419
420                 errorThrown = false;
421                 try {
422                         int i = s1.IndexOfAny(null, 0);
423                 } catch (ArgumentNullException) {
424                         errorThrown = true;
425                 }
426                 Assert("null char[] error", errorThrown);
427
428                 errorThrown = false;
429                 try {
430                         int i = s1.IndexOfAny(null, 0, 1);
431                 } catch (ArgumentNullException) {
432                         errorThrown = true;
433                 }
434                 Assert("null char[] error", errorThrown);
435
436                 char[] c1 = {'a', 'e', 'i', 'o', 'u'};
437                 AssertEquals("first vowel", 0, s1.IndexOfAny(c1));
438                 AssertEquals("second vowel", 4, s1.IndexOfAny(c1, 1));
439                 AssertEquals("out of vowels", -1, s1.IndexOfAny(c1, 9));
440                 AssertEquals("second vowel in range", 
441                              4, s1.IndexOfAny(c1, 1, 4));
442                 AssertEquals("second vowel out of range", 
443                              -1, s1.IndexOfAny(c1, 1, 3));
444
445                 errorThrown = false;
446                 try {
447                         int i = s1.IndexOfAny(c1, s1.Length+1);
448                 } catch (ArgumentOutOfRangeException) {
449                         errorThrown = true;
450                 }
451                 Assert("Out of range error", errorThrown);
452
453                 errorThrown = false;
454                 try {
455                         int i = s1.IndexOfAny(c1, s1.Length+1, 1);
456                 } catch (ArgumentOutOfRangeException) {
457                         errorThrown = true;
458                 }
459                 Assert("Out of range error", errorThrown);
460         }
461
462         public void TestInsert() {
463                 string s1 = "original";
464                 
465                 bool errorThrown = false;
466                 try {
467                         string result = s1.Insert(0, null);
468                 } catch (ArgumentNullException) {
469                         errorThrown = true;
470                 }
471                 Assert("Null arg error", errorThrown);
472
473                 errorThrown = false;
474                 try {
475                         string result = s1.Insert(s1.Length+1, "Hi!");
476                 } catch (ArgumentOutOfRangeException) {
477                         errorThrown = true;
478                 }
479                 Assert("Out of range error", errorThrown);
480
481                 AssertEquals("front insert", 
482                              "Hi!original", s1.Insert(0, "Hi!"));
483                 AssertEquals("back insert", 
484                              "originalHi!", s1.Insert(s1.Length, "Hi!"));
485                 AssertEquals("middle insert", 
486                              "origHi!inal", s1.Insert(4, "Hi!"));
487         }
488
489         public void TestIntern() {
490                 bool errorThrown = false;
491                 try {
492                         string s = String.Intern(null);
493                 } catch (ArgumentNullException) {
494                         errorThrown = true;
495                 }
496                 Assert("null arg error", errorThrown);
497
498                 string s1 = "original";
499                 AssertEquals("One string's reps are both the same",
500                              String.Intern(s1), String.Intern(s1));
501
502                 string s2 = "originally";
503                 Assert("Different strings, different reps",
504                        String.Intern(s1) != String.Intern(s2));
505         }
506
507         public void TestIsInterned() {
508                 bool errorThrown = false;
509                 try {
510                         string s = String.IsInterned(null);
511                 } catch (ArgumentNullException) {
512                         errorThrown = true;
513                 }
514                 Assert("null arg error", errorThrown);
515
516                 // FIXME - it seems like this should work, but no.
517                 //   I don't know how it's possible to get a null
518                 //   returned from IsInterned.
519                 //Assert("no intern for regular string", 
520                 //String.IsInterned("original") == null);
521
522                 string s1 = "original";
523                 AssertEquals("is interned", s1, String.IsInterned(s1));
524         }
525
526         public void TestJoin() {
527                 bool errorThrown = false;
528                 try {
529                         string s = String.Join(" ", null);
530                 } catch (ArgumentNullException) {
531                         errorThrown = true;
532                 }
533                 Assert("null arg error", errorThrown);
534
535                 string[] chunks = {"this", "is", "a", "test"};
536                 AssertEquals("Basic join", "this is a test",
537                              String.Join(" ", chunks));
538                 AssertEquals("Basic join", "this.is.a.test",
539                              String.Join(".", chunks));
540
541                 AssertEquals("Subset join", "is a",
542                              String.Join(" ", chunks, 1, 2));
543                 AssertEquals("Subset join", "is.a",
544                              String.Join(".", chunks, 1, 2));
545                 AssertEquals("Subset join", "is a test",
546                              String.Join(" ", chunks, 1, 3));
547
548                 errorThrown = false;
549                 try {
550                         string s = String.Join(" ", chunks, 2, 3);
551                 } catch (ArgumentOutOfRangeException) {
552                         errorThrown = true;
553                 }
554                 Assert("out of range error", errorThrown);
555         }
556
557         public void TestLastIndexOf() {
558                 string s1 = "original";
559
560                 bool errorThrown = false;
561                 try {
562                         int i = s1.LastIndexOf('q', -1);
563                 } catch (ArgumentOutOfRangeException) {
564                         errorThrown = true;
565                 }
566                 Assert("out of range error for char", errorThrown);
567
568                 errorThrown = false;
569                 try {
570                         int i = s1.LastIndexOf('q', -1, 1);
571                 } catch (ArgumentOutOfRangeException) {
572                         errorThrown = true;
573                 }
574                 Assert("out of range error for char", errorThrown);
575
576                 errorThrown = false;
577                 try {
578                         int i = s1.LastIndexOf("huh", s1.Length + 1);
579                 } catch (ArgumentOutOfRangeException) {
580                         errorThrown = true;
581                 }
582                 Assert("out of range for string", errorThrown);
583
584                 errorThrown = false;
585                 try {
586                         int i = s1.LastIndexOf("huh", s1.Length + 1, 3);
587                 } catch (ArgumentOutOfRangeException) {
588                         errorThrown = true;
589                 }
590                 Assert("out of range for string", errorThrown);
591
592                 errorThrown = false;
593                 try {
594                         int i = s1.LastIndexOf(null);
595                 } catch (ArgumentNullException) {
596                         errorThrown = true;
597                 }
598                 Assert("null string error", errorThrown);
599
600                 errorThrown = false;
601                 try {
602                         int i = s1.LastIndexOf(null, 0);
603                 } catch (ArgumentNullException) {
604                         errorThrown = true;
605                 }
606                 Assert("null string error", errorThrown);
607
608                 errorThrown = false;
609                 try {
610                         int i = s1.LastIndexOf(null, 0, 1);
611                 } catch (ArgumentNullException) {
612                         errorThrown = true;
613                 }
614                 Assert("null string error", errorThrown);
615
616                 AssertEquals("basic char index", 1, s1.LastIndexOf('r'));
617                 AssertEquals("basic char index", 4, s1.LastIndexOf('i'));
618                 AssertEquals("basic char index - no", -1, s1.LastIndexOf('q'));
619                 
620                 AssertEquals("basic string index", 1, s1.LastIndexOf("rig"));
621                 AssertEquals("basic string index", 4, s1.LastIndexOf("i"));
622                 AssertEquals("basic string index - no", -1, 
623                              s1.LastIndexOf("rag"));
624
625
626
627                 AssertEquals("stepped char index", 1, 
628                              s1.LastIndexOf('r', s1.Length-1));
629                 AssertEquals("stepped char index", 4, 
630                              s1.LastIndexOf('i', s1.Length-1));
631                 AssertEquals("stepped char index", 2, 
632                              s1.LastIndexOf('i', 3));
633                 AssertEquals("stepped char index", -1, 
634                              s1.LastIndexOf('i', 1));
635
636                 AssertEquals("stepped limited char index", 
637                              1, s1.LastIndexOf('r', 1, 1));
638                 AssertEquals("stepped limited char index", 
639                              -1, s1.LastIndexOf('r', 0, 1));
640                 AssertEquals("stepped limited char index", 
641                              4, s1.LastIndexOf('i', 6, 3));
642                 AssertEquals("stepped limited char index", 
643                              2, s1.LastIndexOf('i', 3, 3));
644                 AssertEquals("stepped limited char index", 
645                              -1, s1.LastIndexOf('i', 1, 2));
646
647                 s1 = "original original";
648                 AssertEquals("stepped string index #1",
649                              9, s1.LastIndexOf("original", s1.Length));
650                 AssertEquals("stepped string index #2", 
651                              0, s1.LastIndexOf("original", s1.Length-2));
652                 AssertEquals("stepped string index #3", 
653                              -1, s1.LastIndexOf("original", s1.Length-11));
654                 AssertEquals("stepped string index #4",
655                              -1, s1.LastIndexOf("translator", 2));
656                 AssertEquals("stepped limited string index #1",
657                              10, s1.LastIndexOf("rig", s1.Length-1, 10));
658                 AssertEquals("stepped limited string index #2",
659                              -1, s1.LastIndexOf("rig", s1.Length, 3));
660                 AssertEquals("stepped limited string index #3",
661                              10, s1.LastIndexOf("rig", s1.Length-2, 15));
662                 AssertEquals("stepped limited string index #4",
663                              -1, s1.LastIndexOf("rig", s1.Length-2, 3));
664         }
665
666         public void TestLastIndexOfAny() {
667                 string s1 = ".bcdefghijklm";
668
669                 bool errorThrown = false;
670                 try {
671                         int i = s1.LastIndexOfAny(null);
672                 } catch (ArgumentNullException) {
673                         errorThrown = true;
674                 }
675                 Assert("null char[] error", errorThrown);
676
677                 errorThrown = false;
678                 try {
679                         int i = s1.LastIndexOfAny(null, s1.Length);
680                 } catch (ArgumentNullException) {
681                         errorThrown = true;
682                 }
683                 Assert("null char[] error", errorThrown);
684
685                 errorThrown = false;
686                 try {
687                         int i = s1.LastIndexOfAny(null, s1.Length, 1);
688                 } catch (ArgumentNullException) {
689                         errorThrown = true;
690                 }
691                 Assert("null char[] error", errorThrown);
692
693                 char[] c1 = {'a', 'e', 'i', 'o', 'u'};
694                 AssertEquals("first vowel", 8, s1.LastIndexOfAny(c1));
695                 AssertEquals("second vowel", 4, s1.LastIndexOfAny(c1, 7));
696                 AssertEquals("out of vowels", -1, s1.LastIndexOfAny(c1, 3));
697                 AssertEquals("second vowel in range", 
698                              4, s1.LastIndexOfAny(c1, s1.Length-6, 4));
699                 AssertEquals("second vowel out of range", 
700                              -1, s1.LastIndexOfAny(c1, s1.Length-6, 3));
701
702                 errorThrown = false;
703                 try {
704                         int i = s1.LastIndexOfAny(c1, -1);
705                 } catch (ArgumentOutOfRangeException) {
706                         errorThrown = true;
707                 }
708                 Assert("Out of range error", errorThrown);
709
710                 errorThrown = false;
711                 try {
712                         int i = s1.LastIndexOfAny(c1, -1, 1);
713                 } catch (ArgumentOutOfRangeException) {
714                         errorThrown = true;
715                 }
716                 Assert("Out of range error", errorThrown);
717         }
718
719         public void TestPadLeft() {
720                 string s1 = "Hi!";
721
722                 bool errorThrown = false;
723                 try {
724                         string s = s1.PadLeft(-1);
725                 } catch (ArgumentException) {
726                         errorThrown = true;
727                 }
728                 Assert("Bad argument error", errorThrown);
729
730                 AssertEquals("Too little padding",
731                              s1, s1.PadLeft(s1.Length-1));
732                 AssertEquals("Some padding",
733                              "  Hi!", s1.PadLeft(5));
734         }
735
736         public void TestPadRight() {
737                 string s1 = "Hi!";
738
739                 bool errorThrown = false;
740                 try {
741                         string s = s1.PadRight(-1);
742                 } catch (ArgumentException) {
743                         errorThrown = true;
744                 }
745                 Assert("Bad argument error", errorThrown);
746
747                 AssertEquals("Too little padding",
748                              s1, s1.PadRight(s1.Length-1));
749                 AssertEquals("Some padding",
750                              "Hi!  ", s1.PadRight(5));
751         }
752
753         public void TestRemove() {
754                 string s1 = "original";
755
756                 bool errorThrown = false;
757                 try {
758                         s1.Remove(-1,1);
759                 } catch (ArgumentOutOfRangeException) {
760                         errorThrown = true;
761                 }
762                 Assert("out of range error", errorThrown);
763                 errorThrown = false;
764                 try {
765                         s1.Remove(1,-1);
766                 } catch (ArgumentOutOfRangeException) {
767                         errorThrown = true;
768                 }
769                 Assert("out of range error", errorThrown);
770                 errorThrown = false;
771                 try {
772                         s1.Remove(s1.Length,s1.Length);
773                 } catch (ArgumentOutOfRangeException) {
774                         errorThrown = true;
775                 }
776                 Assert("out of range error", errorThrown);
777
778                 AssertEquals("basic remove", "oinal",
779                              s1.Remove(1, 3));
780         }
781
782         public void TestReplace() {
783                 string s1 = "original";
784
785                 AssertEquals("non-hit char", s1, s1.Replace('q','s'));
786                 AssertEquals("single char", "oxiginal", s1.Replace('r', 'x'));
787                 AssertEquals("double char", "orxgxnal", s1.Replace('i', 'x'));
788
789                 bool errorThrown = false;
790                 try {
791                         string s = s1.Replace(null, "feh");
792                 } catch (ArgumentNullException) {
793                         errorThrown = true;
794                 }
795                 Assert("should get null arg exception", errorThrown);
796
797                 AssertEquals("replace as remove", "ornal", 
798                              s1.Replace("igi", null));
799                 AssertEquals("non-hit string", s1, s1.Replace("spam", "eggs"));
800                 AssertEquals("single string", "orirumal", 
801                              s1.Replace("gin", "rum"));
802                 AssertEquals("double string", "oreigeinal", 
803                              s1.Replace("i", "ei"));
804                                                      \r
805                 AssertEquals ("result longer", ":!:", "::".Replace ("::", ":!:"));\r
806         }
807
808         public void TestSplit() {
809                 string s1 = "abcdefghijklm";
810                 char[] c1 = {'q', 'r'};
811                 AssertEquals("No splitters", s1, (s1.Split(c1))[0]);
812
813                 char[] c2 = {'a', 'e', 'i', 'o', 'u'};
814                 string[] chunks = s1.Split(c2);
815                 AssertEquals("First chunk", "", chunks[0]);
816                 AssertEquals("Second chunk", "bcd", chunks[1]);
817                 AssertEquals("Third chunk", "fgh", chunks[2]);
818                 AssertEquals("Fourth chunk", "jklm", chunks[3]);
819
820                 {
821                         bool errorThrown = false;
822                         try {
823                                 chunks = s1.Split(c2, -1);
824                         } catch (ArgumentOutOfRangeException) {
825                                 errorThrown = true;
826                         }
827                         Assert("Split out of range", errorThrown);
828                 }
829
830                 chunks = s1.Split(c2, 2);
831                 AssertEquals("Limited chunk", 2, chunks.Length);
832                 AssertEquals("First limited chunk", "", chunks[0]);
833                 AssertEquals("Second limited chunk", "bcdefghijklm", chunks[1]);
834
835                 string s3 = "1.0";
836                 char[] c3 = {'.'};
837                 chunks = s3.Split(c3,2);
838                 AssertEquals("1.0 split length", 2, chunks.Length);
839                 AssertEquals("1.0 split first chunk", "1", chunks[0]);
840                 AssertEquals("1.0 split second chunk", "0", chunks[1]);
841
842                 string s4 = "1.0.0";
843                 char[] c4 = {'.'};
844                 chunks = s4.Split(c4,2);
845                 AssertEquals("1.0.0 split length", 2, chunks.Length);
846                 AssertEquals("1.0.0 split first chunk", "1", chunks[0]);
847                 AssertEquals("1.0.0 split second chunk", "0.0", chunks[1]);
848
849                 string s5 = ".0.0";
850                 char[] c5 = {'.'};
851                 chunks = s5.Split (c5, 2);
852                 AssertEquals(".0.0 split length", 2, chunks.Length);
853                 AssertEquals(".0.0 split first chunk", "", chunks[0]);
854                 AssertEquals(".0.0 split second chunk", "0.0", chunks[1]);
855
856                 string s6 = ".0";
857                 char[] c6 = {'.'};
858                 chunks = s6.Split (c6, 2);
859                 AssertEquals(".0 split length", 2, chunks.Length);
860                 AssertEquals(".0 split first chunk", "", chunks[0]);
861                 AssertEquals(".0 split second chunk", "0", chunks[1]);
862
863                 string s7 = "0.";
864                 char[] c7 = {'.'};
865                 chunks = s7.Split (c7, 2);
866                 AssertEquals("0. split length", 2, chunks.Length);
867                 AssertEquals("0. split first chunk", "0", chunks[0]);
868                 AssertEquals("0. split second chunk", "", chunks[1]);
869
870                 string s8 = "0.0000";
871                 char[] c8 = {'.'};
872                 chunks = s8.Split (c8, 2);
873                 AssertEquals("0.0000/2 split length", 2, chunks.Length);
874                 AssertEquals("0.0000/2 split first chunk", "0", chunks[0]);
875                 AssertEquals("0.0000/2 split second chunk", "0000", chunks[1]);
876
877                 chunks = s8.Split (c8, 3);
878                 AssertEquals("0.0000/3 split length", 2, chunks.Length);
879                 AssertEquals("0.0000/3 split first chunk", "0", chunks[0]);
880                 AssertEquals("0.0000/3 split second chunk", "0000", chunks[1]);
881
882                 chunks = s8.Split (c8, 1);
883                 AssertEquals("0.0000/1 split length", 1, chunks.Length);
884                 AssertEquals("0.0000/1 split first chunk", "0.0000", chunks[0]);
885
886                 chunks = s1.Split(c2, 1);
887                 AssertEquals("Single split", 1, chunks.Length);
888                 AssertEquals("Single chunk", s1, chunks[0]);
889
890                 chunks = s1.Split(c2, 0);
891                 AssertEquals("Zero split", 0, chunks.Length);
892         }
893
894         public void TestStartsWith() {
895                 string s1 = "original";
896                 
897                 bool errorThrown = false;
898                 try {
899                         bool huh = s1.StartsWith(null);
900                 } catch (ArgumentNullException) {
901                         errorThrown = true;
902                 }
903                 Assert("null StartsWith shouldn't be good", errorThrown);
904
905                 Assert("should match", s1.StartsWith("o"));
906                 Assert("should match 2", s1.StartsWith("orig"));
907                 Assert("should fail", !s1.StartsWith("rig"));
908         }
909
910         public void TestSubstring() {
911                 string s1 = "original";
912
913                 bool errorThrown = false;
914                 try {
915                         string s = s1.Substring(s1.Length+1);
916                 } catch (ArgumentOutOfRangeException) {
917                         errorThrown = true;
918                 }
919                 Assert("error not thrown", errorThrown);
920                 errorThrown = false;
921                 try {
922                         string s = s1.Substring(-1);
923                 } catch (ArgumentOutOfRangeException) {
924                         errorThrown = true;
925                 }
926                 Assert("error not thrown", errorThrown);
927
928                 errorThrown = false;
929                 try {
930                         string s = s1.Substring(1, -1);
931                 } catch (ArgumentOutOfRangeException) {
932                         errorThrown = true;
933                 }
934                 Assert("error not thrown", errorThrown);
935                 errorThrown = false;
936                 try {
937                         string s = s1.Substring(-1, 1);
938                 } catch (ArgumentOutOfRangeException) {
939                         errorThrown = true;
940                 }
941                 Assert("error not thrown", errorThrown);
942                 errorThrown = false;
943                 try {
944                         string s = s1.Substring(s1.Length, 1);
945                 } catch (ArgumentOutOfRangeException) {
946                         errorThrown = true;
947                 }
948                 Assert("error not thrown", errorThrown);
949                 errorThrown = false;
950                 try {
951                         string s = s1.Substring(1, s1.Length);
952                 } catch (ArgumentOutOfRangeException) {
953                         errorThrown = true;
954                 }
955                 Assert("error not thrown", errorThrown);
956
957                 AssertEquals("basic substring", "inal",
958                              s1.Substring(4));
959                 AssertEquals("midstring", "igin",
960                              s1.Substring(2, 4));
961                 AssertEquals("at end", "",
962                              s1.Substring(s1.Length, 0));
963         }
964
965         public void TestToCharArray() {
966                 string s1 = "original";
967                 char[] c1 = s1.ToCharArray();
968                 AssertEquals("right array size", s1.Length, c1.Length);
969                 AssertEquals("basic char array", s1,
970                              new String(c1));
971                 
972                 bool errorThrown = false;
973                 try {
974                         s1.ToCharArray(s1.Length, 1);
975                 } catch (ArgumentOutOfRangeException) {
976                         errorThrown = true;
977                 }
978                 Assert("error not thrown", errorThrown);
979                 errorThrown = false;
980                 try {
981                         s1.ToCharArray(1, s1.Length);
982                 } catch (ArgumentOutOfRangeException) {
983                         errorThrown = true;
984                 }
985                 Assert("error not thrown", errorThrown);
986                 errorThrown = false;
987                 try {
988                         s1.ToCharArray(-1, 1);
989                 } catch (ArgumentOutOfRangeException) {
990                         errorThrown = true;
991                 }
992                 Assert("error not thrown", errorThrown);
993                 errorThrown = false;
994                 try {
995                         s1.ToCharArray(1, -1);
996                 } catch (ArgumentOutOfRangeException) {
997                         errorThrown = true;
998                 }
999                 Assert("error not thrown", errorThrown);
1000
1001                 c1 = s1.ToCharArray(0, 3);
1002                 AssertEquals("Starting char array", "ori", new String(c1));
1003         }
1004
1005         public void TestToLower() {
1006                 string s1 = "OrIgInAl";
1007                 AssertEquals("lowercase failed", "original", s1.ToLower());
1008
1009                 // TODO - Again, with CultureInfo
1010         }
1011
1012         public void TestToString() {
1013                 string s1 = "original";
1014                 AssertEquals("ToString failed!", s1, s1.ToString());
1015         }
1016
1017         public void TestToUpper() {
1018                 string s1 = "OrIgInAl";
1019                 AssertEquals("uppercase failed", "ORIGINAL", s1.ToUpper());
1020
1021                 // TODO - Again, with CultureInfo
1022         }
1023
1024         public void TestTrim() {
1025                 string s1 = "  original\t\n";
1026                 AssertEquals("basic trim failed", "original", s1.Trim());
1027                 AssertEquals("basic trim failed", "original", s1.Trim(null));
1028
1029                 s1 = "original";\r
1030                 AssertEquals("basic trim failed", "original", s1.Trim());\r
1031                 AssertEquals("basic trim failed", "original", s1.Trim(null));\r
1032 \r
1033                 s1 = "   \t \n  ";\r
1034                 AssertEquals("empty trim failed", "", s1.Trim());\r
1035                 AssertEquals("empty trim failed", "", s1.Trim(null));\r
1036 \r
1037                 s1 = "aaaoriginalbbb";
1038                 char[] delims = {'a', 'b'};
1039                 AssertEquals("custom trim failed", 
1040                              "original", s1.Trim(delims));
1041         }
1042
1043         public void TestTrimEnd() {
1044                 string s1 = "  original\t\n";
1045                 AssertEquals("basic TrimEnd failed", 
1046                              "  original", s1.TrimEnd(null));
1047
1048                 s1 = "  original";\r
1049                 AssertEquals("basic TrimEnd failed", \r
1050                              "  original", s1.TrimEnd(null));\r
1051 \r
1052                 s1 = "  \t  \n  \n    ";\r
1053                 AssertEquals("empty TrimEnd failed", \r
1054                              "", s1.TrimEnd(null));\r
1055 \r
1056                 s1 = "aaaoriginalbbb";
1057                 char[] delims = {'a', 'b'};
1058                 AssertEquals("custom TrimEnd failed", 
1059                              "aaaoriginal", s1.TrimEnd(delims));
1060         }
1061
1062         public void TestTrimStart() {
1063                 string s1 = "  original\t\n";
1064                 AssertEquals("basic TrimStart failed", 
1065                              "original\t\n", s1.TrimStart(null));
1066
1067                 s1 = "original\t\n";\r
1068                 AssertEquals("basic TrimStart failed", \r
1069                              "original\t\n", s1.TrimStart(null));\r
1070 \r
1071                 s1 = "    \t \n \n  ";\r
1072                 AssertEquals("empty TrimStart failed", \r
1073                              "", s1.TrimStart(null));\r
1074 \r
1075                 s1 = "aaaoriginalbbb";
1076                 char[] delims = {'a', 'b'};
1077                 AssertEquals("custom TrimStart failed", 
1078                              "originalbbb", s1.TrimStart(delims));
1079         }
1080
1081 }
1082
1083 }