2 // assembly: System_test
3 // namespace: MonoTests.System.Text.RegularExpressions
7 // Juraj Skripsky (juraj@hotfeet.ch)
9 // (c) 2003 Juraj Skripsky
12 using System.Text.RegularExpressions;
15 using System.Collections.Generic;
18 using NUnit.Framework;
20 namespace MonoTests.System.Text.RegularExpressions
24 public class CompiledRegexTest : RegexTest
34 public class InterpretedRegexTest : RegexTest
44 public class RegexTest
47 RegexOptions AddOptions ( RegexOptions options ){
49 options |= RegexOptions.Compiled;
55 protected bool Compiled { get; set; }
58 private int cache_initial_value;
61 public void FixtureSetUp ()
63 cache_initial_value = Regex.CacheSize;
67 public void TearDown ()
69 Regex.CacheSize = cache_initial_value;
76 char[] c = { (char)32, (char)8212, (char)32 };
77 string s = new String(c);
78 Assert.IsTrue (Regex.IsMatch(s, s), "char");
81 [Test, ExpectedException (typeof (ArgumentNullException))]
82 public void NullPattern1 ()
87 [Test, ExpectedException (typeof (ArgumentNullException))]
88 public void NullPattern2 ()
90 new Regex (null, AddOptions( RegexOptions.None ));
93 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
94 public void InvalidOptions1 ()
96 new Regex ("foo", (RegexOptions) Int32.MaxValue);
99 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
100 public void InvalidOptions2 ()
102 new Regex ("foo", AddOptions( RegexOptions.ECMAScript | RegexOptions.RightToLeft ));
106 public void Unescape ()
108 string inString = @"\a\b\t\r\v\f\n\e\02400\x231\cC\ufffff\*";
109 char [] c = { (char)7, (char)8, (char)9, (char)13,
110 (char)11, (char)12, (char)10, (char)27, (char) 20,
111 (char)48, (char)48, (char)35, (char)49,
112 (char)3, (char)65535, (char)102, (char)42
114 string expectedString = new String(c);
115 string outString = Regex.Unescape(inString);
117 Assert.AreEqual (outString, expectedString, "unescape");
121 public void Match1 ()
123 Regex email = new Regex ("(?<user>[^@]+)@(?<domain>.+)",
124 AddOptions( RegexOptions.None ));
127 m = email.Match ("mono@go-mono.com");
129 Assert.IsTrue (m.Success, "#m01");
130 Assert.AreEqual ("mono", m.Groups ["user"].Value, "#m02");
131 Assert.AreEqual ("go-mono.com", m.Groups ["domain"].Value, "#m03");
133 m = email.Match ("mono.bugs@go-mono.com");
134 Assert.IsTrue (m.Success, "m04");
135 Assert.AreEqual ("mono.bugs", m.Groups ["user"].Value, "#m05");
136 Assert.AreEqual ("go-mono.com", m.Groups ["domain"].Value, "#m06");
140 public void Match2 ()
142 Regex regex = new Regex(@"(?<tab>\t)|(?<text>[^\t]*)",
143 AddOptions( RegexOptions.None ));
144 MatchCollection col = regex.Matches("\tjust a text");
145 Assert.AreEqual(3, col.Count);
146 Assert.AreEqual (col [0].Value, "\t");
147 Assert.AreEqual (col [1].Value, "just a text");
148 Assert.AreEqual(col[2].Value, string.Empty);
151 [Test, ExpectedException (typeof (ArgumentNullException))]
152 public void Match_Null1 ()
154 new Regex (@"foo",AddOptions( RegexOptions.None )).Match (null);
157 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
158 public void Match_BadStart1 ()
161 AddOptions( RegexOptions.None )).Match ("foobar", -1);
164 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
165 public void Match_BadStart2 ()
168 AddOptions( RegexOptions.None )).Match ("foobar", -1, 0);
171 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
172 public void Match_BadStart3 ()
175 AddOptions( RegexOptions.None )).Match ("foobar", 7);
178 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
179 public void Match_BadStart4 ()
182 AddOptions( RegexOptions.None )).Match ("foobar", 7, 0);
185 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
186 public void Match_BadLength1 ()
189 AddOptions( RegexOptions.None )).Match ("foobar", 5, -1);
192 [Test, ExpectedException (typeof (IndexOutOfRangeException))]
193 public void Match_BadLength2 ()
196 AddOptions( RegexOptions.None )).Match ("foobar", 5, 3);
199 [Test, ExpectedException (typeof (ArgumentNullException))]
200 public void Matches_Null1 ()
203 AddOptions( RegexOptions.None )).Matches (null);
206 [Test, ExpectedException (typeof (ArgumentNullException))]
207 public void Matches_Null2 ()
210 AddOptions( RegexOptions.None )).Matches (null, 0);
213 [Test, ExpectedException (typeof (ArgumentNullException))]
214 public void Matches_Null3 ()
217 AddOptions(RegexOptions.RightToLeft)).Matches (null);
221 public void Match_SubstringAnchors ()
223 Regex r = new Regex ("^ooba$",
224 AddOptions( RegexOptions.None ));
225 Match m = r.Match ("foobar", 1, 4);
227 Assert.IsTrue (m.Success);
228 Assert.AreEqual ("ooba", m.Value);
232 public void Match_SubstringRtl ()
234 Regex r = new Regex(@".*", RegexOptions.RightToLeft);
235 Match m = r.Match("ABCDEFGHI", 2, 6);
237 Assert.IsTrue (m.Success);
238 Assert.AreEqual ("CDEFGH", m.Value);
241 [Test, ExpectedException (typeof (ArgumentNullException))]
242 public void Replace_InputNull ()
244 Regex r = new Regex ("^.*$",
245 AddOptions( RegexOptions.None ));
246 MatchEvaluator m = delegate (Match match) {return null;};
247 r.Replace (null, m, 0, 0);
250 [Test, ExpectedException (typeof (ArgumentNullException))]
251 public void Replace_InputNull2 ()
253 Regex r = new Regex ("^.*$",
254 AddOptions( RegexOptions.None ));
255 r.Replace (null, "abc", 0, 0);
258 [Test, ExpectedException (typeof (ArgumentNullException))]
259 public void Replace_InputNull3 ()
261 Regex r = new Regex ("^.*$",
262 AddOptions(RegexOptions.RightToLeft));
263 MatchEvaluator m = delegate (Match match) {return null;};
267 [Test, ExpectedException (typeof (ArgumentNullException))]
268 public void Replace_InputNull4 ()
270 Regex r = new Regex ("^.*$",
271 AddOptions(RegexOptions.RightToLeft));
272 r.Replace (null, "abc");
275 [Test, ExpectedException (typeof (ArgumentNullException))]
276 public void Replace_ReplacementNull ()
278 Regex r = new Regex ("^.*$",
279 AddOptions( RegexOptions.None ));
280 r.Replace ("string", (string) null, 0, 0);
283 [Test, ExpectedException (typeof (ArgumentNullException))]
284 public void Replace_EvaluatorNull ()
286 Regex r = new Regex ("^.*$",
287 AddOptions( RegexOptions.None ));
288 MatchEvaluator m = null;
289 r.Replace ("string", m, 0, 0);
292 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
293 public void Replace_InvalidCount ()
295 Regex r = new Regex ("foo|bar",
296 AddOptions( RegexOptions.None ));
297 r.Replace ("foo", "baz", -4);
300 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
301 public void Replace_InvalidStart ()
303 Regex r = new Regex ("foo|bar",
304 AddOptions( RegexOptions.None ));
305 r.Replace ("foo", "baz", 1, -4);
308 [Test, ExpectedException (typeof (ArgumentNullException))]
309 public void Split_InputNull1 ()
311 Regex.Split (null, "^.*$");
314 [Test, ExpectedException (typeof (ArgumentNullException))]
315 public void Split_InputNull2 ()
317 Regex.Split (null, "^.*$", RegexOptions.RightToLeft);
320 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
321 public void Split_InvalidCount ()
323 Regex r = new Regex ("^.*$",
324 AddOptions( RegexOptions.None ));
328 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
329 public void Split_InvalidCount2 ()
331 Regex r = new Regex ("^.*$",
332 AddOptions( RegexOptions.None ));
333 r.Split ("foo", 1, -4);
336 [Test, ExpectedException (typeof (ArgumentNullException))]
337 public void Escape_Null ()
342 [Test, ExpectedException (typeof (ArgumentNullException))]
343 public void Unescape_Null ()
345 Regex.Unescape (null);
348 static string story =
349 "Two little dragons lived in the forest\n" +
350 "They spent their days collecting honey suckle,\n" +
351 "And eating curds and whey\n" +
352 "Until an evil sorcer came along\n" +
353 "And chased my dragon friends away";
355 struct MatchCollectionTrial {
356 public readonly string name;
357 public readonly string text;
358 public readonly string regex;
359 public readonly string [] matches;
360 public MatchCollectionTrial (string name, string text, string regex, string [] matches)
365 this.matches = matches;
369 static readonly MatchCollectionTrial [] trials = {
370 new MatchCollectionTrial ("word", "the fat cat ate the rat", "(?<word>\\w+)",
371 new string [] { "the", "fat", "cat", "ate", "the", "rat" }),
372 new MatchCollectionTrial ("digit", "0 1 2 3 4 5 6a7b8c9d10", "(?<digit>\\d+)",
373 new string [] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }),
374 new MatchCollectionTrial ("line", story, "(?<line>.+)",
375 new string [] { "Two little dragons lived in the forest",
376 "They spent their days collecting honey suckle,",
377 "And eating curds and whey",
378 "Until an evil sorcer came along",
379 "And chased my dragon friends away" }),
380 new MatchCollectionTrial ("nonwhite", "ab 12 cde 456 fghi .,\niou", "(?<nonwhite>\\S+)",
381 new string [] { "ab", "12", "cde", "456", "fghi", ".,", "iou" }),
382 new MatchCollectionTrial ("nondigit", "ab0cd1ef2", "(?<nondigit>\\D+)",
383 new string [] { "ab", "cd", "ef" })
386 static void runTrial (MatchCollectionTrial t, bool compiled)
388 runTrial (t, false, compiled);
389 runTrial (t, true, compiled);
392 static void runTrial (MatchCollectionTrial t, bool rtl, bool compiled)
397 string name = t.name;
401 int len = t.matches.Length;
402 RegexOptions options = rtl ? RegexOptions.RightToLeft : RegexOptions.None;
404 options |= RegexOptions.Compiled;
406 Regex r = new Regex (t.regex,options);
408 // Incremental mode -- this access
409 mc = r.Matches (t.text);
410 for (i = 0; i < len; ++i)
411 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:this:{1}", name, i);
412 Assert.AreEqual (i, mc.Count, "{0}:this:count", name);
414 // Incremental mode -- enumerator
415 mc = r.Matches (t.text);
417 foreach (Match m in mc) {
418 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:enum:{1}", name, i);
421 Assert.AreEqual (i, len, "{0}:enum:count", name);
424 Random rng = new Random ();
425 for (int j = 0; j < len * 5; ++j) {
427 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:random{1}:{2}", name, j, i);
430 // Non-incremental mode
431 mc = r.Matches (t.text);
432 Assert.AreEqual (mc.Count, len);
434 foreach (Match m in mc) {
435 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:nienum:{1}", name, i);
438 for (i = 0; i < len; ++i)
439 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:nithis:{1}", name, i);
443 public void Matches ()
445 foreach (MatchCollectionTrial t in trials)
446 runTrial (t,Compiled);
450 public void CacheSize ()
452 Assert.AreEqual (15, Regex.CacheSize, "CacheSize");
454 Regex.CacheSize = Int32.MaxValue;
458 [ExpectedException (typeof (ArgumentOutOfRangeException))]
459 public void CacheSize_Negative ()
461 Regex.CacheSize = -1;
465 [ExpectedException (typeof (ArgumentOutOfRangeException))]
466 public void CacheSize_Min ()
468 Regex.CacheSize = Int32.MinValue;
471 static IEnumerable<uint> Primes (uint m)
478 Dictionary<uint, uint> w = new Dictionary<uint, uint> ();
481 for (uint n = 3; n < m; n += 2) {
482 if (w.TryGetValue (n, out p2)) {
490 // if there's an overflow, don't bother
491 if (n1 / n != n || n1 >= m)
495 while (w.ContainsKey (n1))
502 public void PrimeRegex ()
504 // Perl regex oneliner by: abigail@fnx.com (Abigail)
505 // from: http://www.mit.edu:8008/bloom-picayune.mit.edu/perl/10138
506 // perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'
508 // This is a backtracking torture test
510 Regex composite = new Regex (@"^1?$|^(11+?)\1+$",
511 AddOptions( RegexOptions.None ));
516 foreach (uint p in Primes (3333)) {
518 Assert.IsTrue (composite.IsMatch (x));
523 Assert.IsFalse (composite.IsMatch (x));