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;
14 using System.Collections.Generic;
16 using NUnit.Framework;
18 namespace MonoTests.System.Text.RegularExpressions
22 public class CompiledRegexTest : RegexTest
32 public class InterpretedRegexTest : RegexTest
42 public class RegexTest
45 RegexOptions AddOptions ( RegexOptions options ){
47 options |= RegexOptions.Compiled;
53 protected bool Compiled { get; set; }
55 private int cache_initial_value;
58 public void FixtureSetUp ()
60 cache_initial_value = Regex.CacheSize;
64 public void TearDown ()
66 Regex.CacheSize = cache_initial_value;
72 char[] c = { (char)32, (char)8212, (char)32 };
73 string s = new String(c);
74 Assert.IsTrue (Regex.IsMatch(s, s), "char");
77 [Test, ExpectedException (typeof (ArgumentNullException))]
78 public void NullPattern1 ()
83 [Test, ExpectedException (typeof (ArgumentNullException))]
84 public void NullPattern2 ()
86 new Regex (null, AddOptions( RegexOptions.None ));
89 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
90 public void InvalidOptions1 ()
92 new Regex ("foo", (RegexOptions) Int32.MaxValue);
95 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
96 public void InvalidOptions2 ()
98 new Regex ("foo", AddOptions( RegexOptions.ECMAScript | RegexOptions.RightToLeft ));
102 public void Unescape ()
104 string inString = @"\a\b\t\r\v\f\n\e\02400\x231\cC\ufffff\*";
105 char [] c = { (char)7, (char)8, (char)9, (char)13,
106 (char)11, (char)12, (char)10, (char)27, (char) 20,
107 (char)48, (char)48, (char)35, (char)49,
108 (char)3, (char)65535, (char)102, (char)42
110 string expectedString = new String(c);
111 string outString = Regex.Unescape(inString);
113 Assert.AreEqual (outString, expectedString, "unescape");
117 public void Match1 ()
119 Regex email = new Regex ("(?<user>[^@]+)@(?<domain>.+)",
120 AddOptions( RegexOptions.None ));
123 m = email.Match ("mono@go-mono.com");
125 Assert.IsTrue (m.Success, "#m01");
126 Assert.AreEqual ("mono", m.Groups ["user"].Value, "#m02");
127 Assert.AreEqual ("go-mono.com", m.Groups ["domain"].Value, "#m03");
129 m = email.Match ("mono.bugs@go-mono.com");
130 Assert.IsTrue (m.Success, "m04");
131 Assert.AreEqual ("mono.bugs", m.Groups ["user"].Value, "#m05");
132 Assert.AreEqual ("go-mono.com", m.Groups ["domain"].Value, "#m06");
136 public void Match2 ()
138 Regex regex = new Regex(@"(?<tab>\t)|(?<text>[^\t]*)",
139 AddOptions( RegexOptions.None ));
140 MatchCollection col = regex.Matches("\tjust a text");
141 Assert.AreEqual(3, col.Count);
142 Assert.AreEqual (col [0].Value, "\t");
143 Assert.AreEqual (col [1].Value, "just a text");
144 Assert.AreEqual(col[2].Value, string.Empty);
147 [Test, ExpectedException (typeof (ArgumentNullException))]
148 public void Match_Null1 ()
150 new Regex (@"foo",AddOptions( RegexOptions.None )).Match (null);
153 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
154 public void Match_BadStart1 ()
157 AddOptions( RegexOptions.None )).Match ("foobar", -1);
160 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
161 public void Match_BadStart2 ()
164 AddOptions( RegexOptions.None )).Match ("foobar", -1, 0);
167 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
168 public void Match_BadStart3 ()
171 AddOptions( RegexOptions.None )).Match ("foobar", 7);
174 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
175 public void Match_BadStart4 ()
178 AddOptions( RegexOptions.None )).Match ("foobar", 7, 0);
181 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
182 public void Match_BadLength1 ()
185 AddOptions( RegexOptions.None )).Match ("foobar", 5, -1);
188 [Test, ExpectedException (typeof (IndexOutOfRangeException))]
189 public void Match_BadLength2 ()
192 AddOptions( RegexOptions.None )).Match ("foobar", 5, 3);
195 [Test, ExpectedException (typeof (ArgumentNullException))]
196 public void Matches_Null1 ()
199 AddOptions( RegexOptions.None )).Matches (null);
202 [Test, ExpectedException (typeof (ArgumentNullException))]
203 public void Matches_Null2 ()
206 AddOptions( RegexOptions.None )).Matches (null, 0);
209 [Test, ExpectedException (typeof (ArgumentNullException))]
210 public void Matches_Null3 ()
213 AddOptions(RegexOptions.RightToLeft)).Matches (null);
217 public void Match_SubstringAnchors ()
219 Regex r = new Regex ("^ooba$",
220 AddOptions( RegexOptions.None ));
221 Match m = r.Match ("foobar", 1, 4);
223 Assert.IsTrue (m.Success);
224 Assert.AreEqual ("ooba", m.Value);
228 public void Match_SubstringRtl ()
230 Regex r = new Regex(@".*", RegexOptions.RightToLeft);
231 Match m = r.Match("ABCDEFGHI", 2, 6);
233 Assert.IsTrue (m.Success);
234 Assert.AreEqual ("CDEFGH", m.Value);
237 [Test, ExpectedException (typeof (ArgumentNullException))]
238 public void Replace_InputNull ()
240 Regex r = new Regex ("^.*$",
241 AddOptions( RegexOptions.None ));
242 MatchEvaluator m = delegate (Match match) {return null;};
243 r.Replace (null, m, 0, 0);
246 [Test, ExpectedException (typeof (ArgumentNullException))]
247 public void Replace_InputNull2 ()
249 Regex r = new Regex ("^.*$",
250 AddOptions( RegexOptions.None ));
251 r.Replace (null, "abc", 0, 0);
254 [Test, ExpectedException (typeof (ArgumentNullException))]
255 public void Replace_InputNull3 ()
257 Regex r = new Regex ("^.*$",
258 AddOptions(RegexOptions.RightToLeft));
259 MatchEvaluator m = delegate (Match match) {return null;};
263 [Test, ExpectedException (typeof (ArgumentNullException))]
264 public void Replace_InputNull4 ()
266 Regex r = new Regex ("^.*$",
267 AddOptions(RegexOptions.RightToLeft));
268 r.Replace (null, "abc");
271 [Test, ExpectedException (typeof (ArgumentNullException))]
272 public void Replace_ReplacementNull ()
274 Regex r = new Regex ("^.*$",
275 AddOptions( RegexOptions.None ));
276 r.Replace ("string", (string) null, 0, 0);
279 [Test, ExpectedException (typeof (ArgumentNullException))]
280 public void Replace_EvaluatorNull ()
282 Regex r = new Regex ("^.*$",
283 AddOptions( RegexOptions.None ));
284 MatchEvaluator m = null;
285 r.Replace ("string", m, 0, 0);
288 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
289 public void Replace_InvalidCount ()
291 Regex r = new Regex ("foo|bar",
292 AddOptions( RegexOptions.None ));
293 r.Replace ("foo", "baz", -4);
296 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
297 public void Replace_InvalidStart ()
299 Regex r = new Regex ("foo|bar",
300 AddOptions( RegexOptions.None ));
301 r.Replace ("foo", "baz", 1, -4);
304 [Test, ExpectedException (typeof (ArgumentNullException))]
305 public void Split_InputNull1 ()
307 Regex.Split (null, "^.*$");
310 [Test, ExpectedException (typeof (ArgumentNullException))]
311 public void Split_InputNull2 ()
313 Regex.Split (null, "^.*$", RegexOptions.RightToLeft);
316 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
317 public void Split_InvalidCount ()
319 Regex r = new Regex ("^.*$",
320 AddOptions( RegexOptions.None ));
324 [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
325 public void Split_InvalidCount2 ()
327 Regex r = new Regex ("^.*$",
328 AddOptions( RegexOptions.None ));
329 r.Split ("foo", 1, -4);
332 [Test, ExpectedException (typeof (ArgumentNullException))]
333 public void Escape_Null ()
338 [Test, ExpectedException (typeof (ArgumentNullException))]
339 public void Unescape_Null ()
341 Regex.Unescape (null);
344 static string story =
345 "Two little dragons lived in the forest\n" +
346 "They spent their days collecting honey suckle,\n" +
347 "And eating curds and whey\n" +
348 "Until an evil sorcer came along\n" +
349 "And chased my dragon friends away";
351 struct MatchCollectionTrial {
352 public readonly string name;
353 public readonly string text;
354 public readonly string regex;
355 public readonly string [] matches;
356 public MatchCollectionTrial (string name, string text, string regex, string [] matches)
361 this.matches = matches;
365 static readonly MatchCollectionTrial [] trials = {
366 new MatchCollectionTrial ("word", "the fat cat ate the rat", "(?<word>\\w+)",
367 new string [] { "the", "fat", "cat", "ate", "the", "rat" }),
368 new MatchCollectionTrial ("digit", "0 1 2 3 4 5 6a7b8c9d10", "(?<digit>\\d+)",
369 new string [] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }),
370 new MatchCollectionTrial ("line", story, "(?<line>.+)",
371 new string [] { "Two little dragons lived in the forest",
372 "They spent their days collecting honey suckle,",
373 "And eating curds and whey",
374 "Until an evil sorcer came along",
375 "And chased my dragon friends away" }),
376 new MatchCollectionTrial ("nonwhite", "ab 12 cde 456 fghi .,\niou", "(?<nonwhite>\\S+)",
377 new string [] { "ab", "12", "cde", "456", "fghi", ".,", "iou" }),
378 new MatchCollectionTrial ("nondigit", "ab0cd1ef2", "(?<nondigit>\\D+)",
379 new string [] { "ab", "cd", "ef" })
382 static void runTrial (MatchCollectionTrial t, bool compiled)
384 runTrial (t, false, compiled);
385 runTrial (t, true, compiled);
388 static void runTrial (MatchCollectionTrial t, bool rtl, bool compiled)
393 string name = t.name;
397 int len = t.matches.Length;
398 RegexOptions options = rtl ? RegexOptions.RightToLeft : RegexOptions.None;
400 options |= RegexOptions.Compiled;
402 Regex r = new Regex (t.regex,options);
404 // Incremental mode -- this access
405 mc = r.Matches (t.text);
406 for (i = 0; i < len; ++i)
407 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:this:{1}", name, i);
408 Assert.AreEqual (i, mc.Count, "{0}:this:count", name);
410 // Incremental mode -- enumerator
411 mc = r.Matches (t.text);
413 foreach (Match m in mc) {
414 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:enum:{1}", name, i);
417 Assert.AreEqual (i, len, "{0}:enum:count", name);
420 Random rng = new Random ();
421 for (int j = 0; j < len * 5; ++j) {
423 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:random{1}:{2}", name, j, i);
426 // Non-incremental mode
427 mc = r.Matches (t.text);
428 Assert.AreEqual (mc.Count, len);
430 foreach (Match m in mc) {
431 Assert.AreEqual (m.Value, t.matches [rtl ? len - i - 1 : i], "{0}:nienum:{1}", name, i);
434 for (i = 0; i < len; ++i)
435 Assert.AreEqual (mc [i].Value, t.matches [rtl ? len - i - 1 : i], "{0}:nithis:{1}", name, i);
439 public void Matches ()
441 foreach (MatchCollectionTrial t in trials)
442 runTrial (t,Compiled);
445 public void CacheSize ()
447 Assert.AreEqual (15, Regex.CacheSize, "CacheSize");
449 Regex.CacheSize = Int32.MaxValue;
453 [ExpectedException (typeof (ArgumentOutOfRangeException))]
454 public void CacheSize_Negative ()
456 Regex.CacheSize = -1;
460 [ExpectedException (typeof (ArgumentOutOfRangeException))]
461 public void CacheSize_Min ()
463 Regex.CacheSize = Int32.MinValue;
466 static IEnumerable<uint> Primes (uint m)
473 Dictionary<uint, uint> w = new Dictionary<uint, uint> ();
476 for (uint n = 3; n < m; n += 2) {
477 if (w.TryGetValue (n, out p2)) {
485 // if there's an overflow, don't bother
486 if (n1 / n != n || n1 >= m)
490 while (w.ContainsKey (n1))
497 public void PrimeRegex ()
499 // Perl regex oneliner by: abigail@fnx.com (Abigail)
500 // from: http://www.mit.edu:8008/bloom-picayune.mit.edu/perl/10138
501 // perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'
503 // This is a backtracking torture test
505 Regex composite = new Regex (@"^1?$|^(11+?)\1+$",
506 AddOptions( RegexOptions.None ));
511 foreach (uint p in Primes (3333)) {
513 Assert.IsTrue (composite.IsMatch (x));
518 Assert.IsFalse (composite.IsMatch (x));