Regex tests. Initial revision - just the Perl trials.
[mono.git] / mcs / class / System / Test / System.Text.RegularExpressions / PerlTest.cs
1 //\r
2 // assembly:    System_test\r
3 // namespace:   MonoTests.System.Text.RegularExpressions\r
4 // file:        PerlTest.cs\r
5 //\r
6 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
7 //              (c) 2002\r
8 \r
9 using System;\r
10 using System.Text.RegularExpressions;\r
11 \r
12 using NUnit.Framework;\r
13 \r
14 namespace MonoTests.System.Text.RegularExpressions {\r
15         \r
16         public class PerlTest : TestCase {\r
17                 public static ITest Suite {\r
18                         get { return new TestSuite (typeof (PerlTest)); }\r
19                 }\r
20 \r
21                 public PerlTest () : this ("System.Text.RegularExpressions Perl testsuite") { }\r
22                 public PerlTest (string name) : base (name) { }\r
23 \r
24                 public void TestTrials () {\r
25                         foreach (RegexTrial trial in PerlTrials.trials) {\r
26                                 string msg = trial.Execute ();\r
27                                 if (msg != null)\r
28                                         Assertion.Fail (msg);\r
29                         }\r
30                 }\r
31 \r
32                 protected override void SetUp () { }\r
33                 protected override void TearDown () { }\r
34         }\r
35 \r
36         class RegexTrial {\r
37                 public string pattern;\r
38                 public RegexOptions options;\r
39                 public string input;\r
40 \r
41                 public Result expected;\r
42                 public uint checksum;\r
43 \r
44                 public RegexTrial (string pattern, RegexOptions options, string input, Result expected, uint checksum) {\r
45                         this.pattern = pattern;\r
46                         this.options = options;\r
47                         this.input = input;\r
48                         this.expected = expected;\r
49                         this.checksum = checksum;\r
50                 }\r
51 \r
52                 public string Execute () {\r
53                         try {\r
54                                 Regex re = new Regex (pattern, options);\r
55                                 Match m = re.Match (input);\r
56 \r
57                                 if (m.Success) {\r
58                                         uint sum = CreateChecksum (re, m);\r
59                                         return Report (Result.Pass, sum);\r
60                                 }\r
61 \r
62                                 return Report (Result.Fail, 0);\r
63                         }\r
64                         catch (Exception) {\r
65                                 return Report (Result.Error, 0);\r
66                         }\r
67                 }\r
68 \r
69                 public override string ToString () {\r
70                         return\r
71                                 "Matching input '" + input +\r
72                                 "' against pattern '" + pattern +\r
73                                 "' with options '" + options + "'.";\r
74                 }\r
75 \r
76                 // private\r
77 \r
78                 private static uint CreateChecksum (Regex re, Match m) {\r
79                         Checksum sum = new Checksum ();\r
80                 \r
81                         // group name mapping\r
82 \r
83                         string[] names = re.GetGroupNames ();\r
84                         foreach (string name in re.GetGroupNames ()) {\r
85                                 sum.Add (name);\r
86                                 sum.Add ((uint)re.GroupNumberFromName (name));\r
87                         }\r
88 \r
89                         // capture history\r
90 \r
91                         foreach (Group group in m.Groups) {\r
92                                 foreach (Capture cap in group.Captures) {\r
93                                         sum.Add ((uint)cap.Index);\r
94                                         sum.Add ((uint)cap.Length);\r
95                                 }\r
96                         }\r
97 \r
98                         return sum.Value;\r
99                 }\r
100 \r
101                 private string Report (Result actual, uint sum) {\r
102                         if (actual == expected && sum == checksum)\r
103                                 return null;\r
104 \r
105                         string msg = this.ToString ();\r
106                         if (actual != expected) {\r
107                                 msg +=\r
108                                         " Expected " + expected +\r
109                                         ", but result was " + actual + ".";\r
110                         }\r
111 \r
112                         if (sum != checksum)\r
113                                 msg += " Bad checksum.";\r
114 \r
115                         return msg;\r
116                 }\r
117 \r
118         }\r
119 \r
120         enum Result {\r
121                 Pass,\r
122                 Fail,\r
123                 Error\r
124         }\r
125 \r
126         class Checksum {\r
127                 public Checksum () {\r
128                         this.sum = 0;\r
129                 }\r
130 \r
131                 public uint Value {\r
132                         get { return sum; }\r
133                 }\r
134 \r
135                 public void Add (string str) {\r
136                         for (int i = 0; i < str.Length; ++ i)\r
137                                 Add (str[i], 16);\r
138                 }\r
139 \r
140                 public void Add (uint n) {\r
141                         Add (n, 32);\r
142                 }\r
143 \r
144                 public void Add (ulong n, int bits) {\r
145                         ulong mask = 1ul << (bits - 1);\r
146                         for (int i = 0; i < bits; ++ i) {\r
147                                 Add ((n & mask) != 0);\r
148                                 mask >>= 1;\r
149                         }\r
150                 }\r
151 \r
152                 public void Add (bool bit) {\r
153                         bool top = (sum & 0x80000000) != 0;\r
154                         sum <<= 1;\r
155                         sum ^= bit ? (uint)1 : (uint)0;\r
156 \r
157                         if (top)\r
158                                 sum ^= key;\r
159                 }\r
160 \r
161                 private uint sum;\r
162                 private readonly uint key = 0x04c11db7;\r
163         }\r
164 }\r