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 (ArgumentOutOfRangeException))]
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);
220 [Test, ExpectedException (typeof (ArgumentNullException))]
221 public void Replace_InputNull ()
223 Regex r = new Regex ("^.*$",
224 AddOptions( RegexOptions.None ));
225 MatchEvaluator m = delegate (Match match) {return null;};
226 r.Replace (null, m, 0, 0);
229 [Test, ExpectedException (typeof (ArgumentNullException))]
230 public void Replace_InputNull2 ()
232 Regex r = new Regex ("^.*$",
233 AddOptions( RegexOptions.None ));
234 r.Replace (null, "abc", 0, 0);
237 [Test, ExpectedException (typeof (ArgumentNullException))]
238 public void Replace_InputNull3 ()
240 Regex r = new Regex ("^.*$",
241 AddOptions(RegexOptions.RightToLeft));
242 MatchEvaluator m = delegate (Match match) {return null;};
246 [Test, ExpectedException (typeof (ArgumentNullException))]
247 public void Replace_InputNull4 ()
249 Regex r = new Regex ("^.*$",
250 AddOptions(RegexOptions.RightToLeft));
251 r.Replace (null, "abc");
254 [Test, ExpectedException (typeof (ArgumentNullException))]
255 public void Replace_ReplacementNull ()
257 Regex r = new Regex ("^.*$",
258 AddOptions( RegexOptions.None ));
259 r.Replace ("string", (string) null, 0, 0);
262 [Test, ExpectedException (typeof (ArgumentNullException))]
263 public void Replace_EvaluatorNull ()
265 Regex r = new Regex ("^.*$",
266 AddOptions( RegexOptions.None ));
267 MatchEvaluator m = null;
268 r.Replace ("string", m, 0, 0);
271 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
272 public void Replace_InvalidCount ()
274 Regex r = new Regex ("foo|bar",
275 AddOptions( RegexOptions.None ));
276 r.Replace ("foo", "baz", -4);
279 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
280 public void Replace_InvalidStart ()
282 Regex r = new Regex ("foo|bar",
283 AddOptions( RegexOptions.None ));
284 r.Replace ("foo", "baz", 1, -4);
287 [Test, ExpectedException (typeof (ArgumentNullException))]
288 public void Split_InputNull1 ()
290 Regex.Split (null, "^.*$");
293 [Test, ExpectedException (typeof (ArgumentNullException))]
294 public void Split_InputNull2 ()
296 Regex.Split (null, "^.*$", RegexOptions.RightToLeft);
299 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
300 public void Split_InvalidCount ()
302 Regex r = new Regex ("^.*$",
303 AddOptions( RegexOptions.None ));
307 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
308 public void Split_InvalidCount2 ()
310 Regex r = new Regex ("^.*$",
311 AddOptions( RegexOptions.None ));
312 r.Split ("foo", 1, -4);
315 [Test, ExpectedException (typeof (ArgumentNullException))]
316 public void Escape_Null ()
321 [Test, ExpectedException (typeof (ArgumentNullException))]
322 public void Unescape_Null ()
324 Regex.Unescape (null);
327 static string story =
328 "Two little dragons lived in the forest\n" +
329 "They spent their days collecting honey suckle,\n" +
330 "And eating curds and whey\n" +
331 "Until an evil sorcer came along\n" +
332 "And chased my dragon friends away";
334 struct MatchCollectionTrial {
335 public readonly string name;
336 public readonly string text;
337 public readonly string regex;
338 public readonly string [] matches;
339 public MatchCollectionTrial (string name, string text, string regex, string [] matches)
344 this.matches = matches;
348 static readonly MatchCollectionTrial [] trials = {
349 new MatchCollectionTrial ("word", "the fat cat ate the rat", "(?<word>\\w+)",
350 new string [] { "the", "fat", "cat", "ate", "the", "rat" }),
351 new MatchCollectionTrial ("digit", "0 1 2 3 4 5 6a7b8c9d10", "(?<digit>\\d+)",
352 new string [] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }),
353 new MatchCollectionTrial ("line", story, "(?<line>.+)",
354 new string [] { "Two little dragons lived in the forest",
355 "They spent their days collecting honey suckle,",
356 "And eating curds and whey",
357 "Until an evil sorcer came along",
358 "And chased my dragon friends away" }),
359 new MatchCollectionTrial ("nonwhite", "ab 12 cde 456 fghi .,\niou", "(?<nonwhite>\\S+)",
360 new string [] { "ab", "12", "cde", "456", "fghi", ".,", "iou" }),
361 new MatchCollectionTrial ("nondigit", "ab0cd1ef2", "(?<nondigit>\\D+)",
362 new string [] { "ab", "cd", "ef" })
365 static void runTrial (MatchCollectionTrial t, bool compiled)
367 runTrial (t, false, compiled);
368 runTrial (t, true, compiled);
371 static void runTrial (MatchCollectionTrial t, bool rtl, bool compiled)
376 string name = t.name;
380 int len = t.matches.Length;
381 RegexOptions options = rtl ? RegexOptions.RightToLeft : RegexOptions.None;
383 options |= RegexOptions.Compiled;
385 Regex r = new Regex (t.regex,options);
387 // Incremental mode -- this access
388 mc = r.Matches (t.text);
389 for (i = 0; i < len; ++i)
390 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:this:{1}", name, i);
391 Assert.AreEqual (i, mc.Count, "{0}:this:count", name);
393 // Incremental mode -- enumerator
394 mc = r.Matches (t.text);
396 foreach (Match m in mc) {
397 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:enum:{1}", name, i);
400 Assert.AreEqual (i, len, "{0}:enum:count", name);
403 Random rng = new Random ();
404 for (int j = 0; j < len * 5; ++j) {
406 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:random{1}:{2}", name, j, i);
409 // Non-incremental mode
410 mc = r.Matches (t.text);
411 Assert.AreEqual (mc.Count, len);
413 foreach (Match m in mc) {
414 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:nienum:{1}", name, i);
417 for (i = 0; i < len; ++i)
418 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:nithis:{1}", name, i);
422 public void Matches ()
424 foreach (MatchCollectionTrial t in trials)
425 runTrial (t,Compiled);
429 public void CacheSize ()
431 Assert.AreEqual (15, Regex.CacheSize, "CacheSize");
433 Regex.CacheSize = Int32.MaxValue;
437 [ExpectedException (typeof (ArgumentOutOfRangeException))]
438 public void CacheSize_Negative ()
440 Regex.CacheSize = -1;
444 [ExpectedException (typeof (ArgumentOutOfRangeException))]
445 public void CacheSize_Min ()
447 Regex.CacheSize = Int32.MinValue;
450 static IEnumerable<uint> Primes (uint m)
457 Dictionary<uint, uint> w = new Dictionary<uint, uint> ();
460 for (uint n = 3; n < m; n += 2) {
461 if (w.TryGetValue (n, out p2)) {
469 // if there's an overflow, don't bother
470 if (n1 / n != n || n1 >= m)
474 while (w.ContainsKey (n1))
481 public void PrimeRegex ()
483 // Perl regex oneliner by: abigail@fnx.com (Abigail)
484 // from: http://www.mit.edu:8008/bloom-picayune.mit.edu/perl/10138
485 // perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'
487 // This is a backtracking torture test
489 Regex composite = new Regex (@"^1?$|^(11+?)\1+$",
490 AddOptions( RegexOptions.None ));
495 foreach (uint p in Primes (3333)) {
497 Assert.IsTrue (composite.IsMatch (x));
502 Assert.IsFalse (composite.IsMatch (x));