Merge pull request #1304 from slluis/mac-proxy-autoconfig
[mono.git] / mcs / class / System / Test / System.Text.RegularExpressions / RegexTest.cs
index 892ad9266905d421e29807ae3916a3a668ef6855..f5208ce99de0e39dfdea201a5222d945b471e435 100644 (file)
 using System;
 using System.Text.RegularExpressions;
 
+#if NET_2_0
+using System.Collections.Generic;
+#endif
+
 using NUnit.Framework;
 
-namespace MonoTests.System.Text.RegularExpressions {
-       
+namespace MonoTests.System.Text.RegularExpressions
+{
+
        [TestFixture]
-       public class RegexTest {
+       public class CompiledRegexTest :  RegexTest
+       {
+               [SetUp]
+        public void SetUp ()
+               {
+                       Compiled = true;
+               }
+       }
+
+       [TestFixture]
+       public class InterpretedRegexTest :  RegexTest
+       {
+        [SetUp]
+        public void SetUp ()
+        {
+               Compiled = false;
+        }
+       }
+
+
+       public class RegexTest
+       {
+
+       RegexOptions AddOptions ( RegexOptions options ){
+              if( Compiled ){
+                      options |= RegexOptions.Compiled;
+              }
+
+              return options;
+       }
+
+       protected bool Compiled { get; set; }
 
 #if NET_2_0
                private int cache_initial_value;
@@ -33,13 +69,38 @@ namespace MonoTests.System.Text.RegularExpressions {
                        Regex.CacheSize = cache_initial_value;
                }
 #endif
+
                [Test]
                public void Simple ()
                {
                        char[] c = { (char)32, (char)8212, (char)32 };
-                       string s = new String(c);                       
+                       string s = new String(c);
                        Assert.IsTrue (Regex.IsMatch(s, s), "char");
                }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void NullPattern1 ()
+               {
+                       new Regex (null);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void NullPattern2 ()
+               {
+                       new Regex (null, AddOptions( RegexOptions.None ));
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void InvalidOptions1 ()
+               {
+                       new Regex ("foo", (RegexOptions) Int32.MaxValue);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void InvalidOptions2 ()
+               {
+                       new Regex ("foo", AddOptions( RegexOptions.ECMAScript | RegexOptions.RightToLeft ));
+               }
                
                [Test]
                public void Unescape ()
@@ -59,7 +120,8 @@ namespace MonoTests.System.Text.RegularExpressions {
                [Test]
                public void Match1 ()
                {
-                       Regex email = new Regex ("(?<user>[^@]+)@(?<domain>.+)");
+                       Regex email = new Regex ("(?<user>[^@]+)@(?<domain>.+)",
+                                                AddOptions( RegexOptions.None ));
                        Match m;
 
                        m = email.Match ("mono@go-mono.com");
@@ -74,7 +136,216 @@ namespace MonoTests.System.Text.RegularExpressions {
                        Assert.AreEqual ("go-mono.com", m.Groups ["domain"].Value, "#m06");
                }
 
-               static string story =   
+               [Test]
+               public void Match2 ()
+               {
+                       Regex regex = new Regex(@"(?<tab>\t)|(?<text>[^\t]*)",
+                                               AddOptions( RegexOptions.None ));
+                       MatchCollection col = regex.Matches("\tjust a text");
+                       Assert.AreEqual(3, col.Count);
+                       Assert.AreEqual (col [0].Value, "\t");
+                       Assert.AreEqual (col [1].Value, "just a text");
+                       Assert.AreEqual(col[2].Value, string.Empty);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Match_Null1 ()
+               {
+                       new Regex (@"foo",AddOptions( RegexOptions.None )).Match (null);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadStart1 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", -1);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadStart2 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", -1, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadStart3 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", 7);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadStart4 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", 7, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadLength1 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", 5, -1);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Match_BadLength2 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Match ("foobar", 5, 3);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Matches_Null1 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Matches (null);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Matches_Null2 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions( RegexOptions.None )).Matches (null, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Matches_Null3 ()
+               {
+                       new Regex (@"foo",
+                                  AddOptions(RegexOptions.RightToLeft)).Matches (null);
+               }
+
+               [Test]
+               public void Match_SubstringAnchors ()
+               {
+                       Regex r = new Regex ("^ooba$",
+                                            AddOptions( RegexOptions.None ));
+                       Match m = r.Match ("foobar", 1, 4);
+
+                       Assert.IsTrue (m.Success);
+                       Assert.AreEqual ("ooba", m.Value);
+               }
+
+               [Test]
+               public void Match_SubstringRtl ()
+               {
+                       Regex r = new Regex(@".*", RegexOptions.RightToLeft);
+                       Match m = r.Match("ABCDEFGHI", 2, 6);
+
+                       Assert.IsTrue (m.Success);
+                       Assert.AreEqual ("CDEFGH", m.Value);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_InputNull ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       MatchEvaluator m = delegate (Match match) {return null;};
+                       r.Replace (null, m, 0, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_InputNull2 ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       r.Replace (null, "abc", 0, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_InputNull3 ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions(RegexOptions.RightToLeft));
+                       MatchEvaluator m = delegate (Match match) {return null;};
+                       r.Replace (null, m);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_InputNull4 ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions(RegexOptions.RightToLeft));
+                       r.Replace (null, "abc");
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_ReplacementNull ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       r.Replace ("string", (string) null, 0, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Replace_EvaluatorNull ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       MatchEvaluator m = null;
+                       r.Replace ("string", m, 0, 0);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Replace_InvalidCount ()
+               {
+                       Regex r = new Regex ("foo|bar",
+                                            AddOptions( RegexOptions.None ));
+                       r.Replace ("foo",  "baz", -4);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Replace_InvalidStart ()
+               {
+                       Regex r = new Regex ("foo|bar",
+                                            AddOptions( RegexOptions.None ));
+                       r.Replace ("foo", "baz", 1, -4);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Split_InputNull1 ()
+               {
+                       Regex.Split (null, "^.*$");
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Split_InputNull2 ()
+               {
+                       Regex.Split (null, "^.*$", RegexOptions.RightToLeft);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Split_InvalidCount ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       r.Split ("foo", -4);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void Split_InvalidCount2 ()
+               {
+                       Regex r = new Regex ("^.*$",
+                                            AddOptions( RegexOptions.None ));
+                       r.Split ("foo", 1, -4);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Escape_Null ()
+               {
+                       Regex.Escape (null);
+               }
+
+               [Test, ExpectedException (typeof (ArgumentNullException))]
+               public void Unescape_Null ()
+               {
+                       Regex.Unescape (null);
+               }
+
+               static string story =
                        "Two little dragons lived in the forest\n" +
                        "They spent their days collecting honey suckle,\n" +
                        "And eating curds and whey\n" +
@@ -112,13 +383,13 @@ namespace MonoTests.System.Text.RegularExpressions {
                                new string [] { "ab", "cd", "ef" })
                };
 
-               static void runTrial (MatchCollectionTrial t)
+               static void runTrial (MatchCollectionTrial t, bool compiled)
                {
-                       runTrial (t, false);
-                       runTrial (t, true);
+                       runTrial (t, false, compiled);
+                       runTrial (t, true, compiled);
                }
 
-               static void runTrial (MatchCollectionTrial t, bool rtl)
+               static void runTrial (MatchCollectionTrial t, bool rtl, bool compiled)
                {
                        int i;
                        MatchCollection mc;
@@ -128,7 +399,11 @@ namespace MonoTests.System.Text.RegularExpressions {
                                name += "-rtl";
 
                        int len = t.matches.Length;
-                       Regex r = new Regex (t.regex, rtl ? RegexOptions.RightToLeft : RegexOptions.None);
+                       RegexOptions options = rtl ? RegexOptions.RightToLeft : RegexOptions.None;
+                       if( compiled )
+                               options |= RegexOptions.Compiled;
+
+                       Regex r = new Regex (t.regex,options);
 
                        // Incremental mode -- this access
                        mc = r.Matches (t.text);
@@ -167,11 +442,8 @@ namespace MonoTests.System.Text.RegularExpressions {
                [Test]
                public void Matches ()
                {
-                       int i;
-                       MatchCollection mc;
-                       Regex r;
                        foreach (MatchCollectionTrial t in trials)
-                               runTrial (t);
+                               runTrial (t,Compiled);
                }
 #if NET_2_0
                [Test]
@@ -195,6 +467,64 @@ namespace MonoTests.System.Text.RegularExpressions {
                {
                        Regex.CacheSize = Int32.MinValue;
                }
+
+               static IEnumerable<uint> Primes (uint m)
+               {
+                       if (m < 2)
+                               yield break;
+
+                       yield return 2;
+
+                       Dictionary<uint, uint> w = new Dictionary<uint, uint> ();
+                       uint p2, n1;
+
+                       for (uint n = 3; n < m; n += 2) {
+                               if (w.TryGetValue (n, out p2)) {
+                                       w.Remove (n);
+                                       n1 = n + p2;
+                               } else {
+                                       yield return n;
+                                       n1 = n * n;
+                                       p2 = n + n;
+
+                                       // if there's an overflow, don't bother
+                                       if (n1 / n != n || n1 >= m)
+                                               continue;
+                               }
+
+                               while (w.ContainsKey (n1))
+                                       n1 += p2;
+                               w [n1] = p2;
+                       }
+               }
+
+               [Test]
+               public void PrimeRegex ()
+               {
+                       // Perl regex oneliner by: abigail@fnx.com (Abigail)
+                       // from: http://www.mit.edu:8008/bloom-picayune.mit.edu/perl/10138
+                       // perl -wle 'print "Prime" if (1 x shift) !~ /^1?$|^(11+?)\1+$/'
+
+                       // This is a backtracking torture test
+
+                       Regex composite = new Regex (@"^1?$|^(11+?)\1+$",
+                                                    AddOptions( RegexOptions.None ));
+
+                       uint i = 0;
+                       string x = "";
+
+                       foreach (uint p in Primes (3333)) {
+                               while (i < p) {
+                                       Assert.IsTrue (composite.IsMatch (x));
+                                       ++i;
+                                       x += "1";
+                               }
+                               // i == p
+                               Assert.IsFalse (composite.IsMatch (x));
+                               ++i;
+                               x += "1";
+                       }
+               }
 #endif
        }
 }