3 * Copyright (C)2007-2009 Versabanq Innovations Inc. and contributors.
4 * Licensed under the GNU Library General Public License, version 2.
5 * See the included file named LICENSE for license information.
8 using System.Collections.Generic;
9 using System.Reflection;
10 using System.Runtime.Serialization;
13 // We put this in wvtest.cs since wvtest.cs should be able to compile all
14 // by itself, without relying on any other parts of wvdotnet. On the other
15 // hand, it's perfectly fine for wvdotnet to have wvtest.cs in it.
18 public static class WvReflection
20 public static IEnumerable<Type> find_types(Type attrtype)
22 foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
24 foreach (Type t in a.GetTypes())
26 if (!t.IsDefined(attrtype, false))
34 public static IEnumerable<MethodInfo> find_methods(this Type t,
37 foreach (MethodInfo m in t.GetMethods())
39 if (!m.IsDefined(attrtype, false))
57 public TestInfo(string name, Action cb)
58 { this.name = name; this.cb = cb; }
60 List<TestInfo> tests = new List<TestInfo>();
62 public int failures { get; private set; }
67 WvReflection.find_types(typeof(TestFixtureAttribute)))
69 foreach (MethodInfo m in
70 t.find_methods(typeof(TestAttribute)))
72 // The new t2, m2 are needed so that each delegate gets
73 // its own copy of the variable.
76 RegisterTest(String.Format("{0}/{1}",
80 m2.Invoke(Activator.CreateInstance(t2),
82 } catch (TargetInvocationException e) {
83 throw e.InnerException;
90 public void RegisterTest(string name, Action tc)
92 tests.Add(new TestInfo(name, tc));
95 public static void DoMain()
97 // Enough to run an entire test
98 Environment.Exit(new WvTest().Run());
103 string[] args = Environment.GetCommandLineArgs();
105 if (args.Length <= 1)
106 Console.WriteLine("WvTest: Running all tests");
108 Console.WriteLine("WvTest: Running only selected tests");
110 foreach (TestInfo test in tests)
112 string[] parts = test.name.Split(new char[] { '/' }, 2);
114 bool runthis = (args.Length <= 1);
115 foreach (string arg in args)
116 if (parts[0].StartsWith(arg) || parts[1].StartsWith(arg))
119 if (!runthis) continue;
121 Console.WriteLine("\nTesting \"{0}\" in {1}:",
126 } catch (WvAssertionFailure) {
128 } catch (Exception e) {
129 Console.WriteLine(e.ToString());
130 Console.WriteLine("! WvTest Exception received FAILED");
135 Console.Out.WriteLine("Result: {0} failures.", failures);
137 // Return a safe unix exit code
138 return failures > 0 ? 1 : 0;
141 public static bool booleanize(bool x)
146 public static bool booleanize(long x)
151 public static bool booleanize(ulong x)
156 public static bool booleanize(string s)
158 return s != null && s != "";
161 public static bool booleanize(object o)
166 static bool expect_fail = false;
167 public static void expect_next_failure()
172 public static bool test(bool ok, string file, int line, string s)
174 s = s.Replace("\n", "!");
175 s = s.Replace("\r", "!");
180 suffix = " (expected) ok";
182 suffix = " (expected fail!) FAILED";
184 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}{4}",
186 ok ? "ok" : "FAILED",
192 throw new WvAssertionFailure(String.Format("{0}:{1} {2}", file, line, s));
197 public static void test_exception(string file, int line, string s)
199 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}",
200 file, line, s, "EXCEPTION");
204 public static bool test_eq(bool cond1, bool cond2,
205 string file, int line,
206 string s1, string s2)
208 return test(cond1 == cond2, file, line,
209 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
210 cond1, cond2, s1, s2));
213 public static bool test_eq(long cond1, long cond2,
214 string file, int line,
215 string s1, string s2)
217 return test(cond1 == cond2, file, line,
218 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
219 cond1, cond2, s1, s2));
222 public static bool test_eq(ulong cond1, ulong cond2,
223 string file, int line,
224 string s1, string s2)
226 return test(cond1 == cond2, file, line,
227 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
228 cond1, cond2, s1, s2));
231 public static bool test_eq(double cond1, double cond2,
232 string file, int line,
233 string s1, string s2)
235 return test(cond1 == cond2, file, line,
236 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
237 cond1, cond2, s1, s2));
240 public static bool test_eq(decimal cond1, decimal cond2,
241 string file, int line,
242 string s1, string s2)
244 return test(cond1 == cond2, file, line,
245 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
246 cond1, cond2, s1, s2));
249 public static bool test_eq(string cond1, string cond2,
250 string file, int line,
251 string s1, string s2)
253 return test(cond1 == cond2, file, line,
254 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
255 cond1, cond2, s1, s2));
258 // some objects can compare themselves to 'null', which is helpful.
259 // for example, DateTime.MinValue == null, but only through
260 // IComparable, not through IObject.
261 public static bool test_eq(IComparable cond1, IComparable cond2,
262 string file, int line,
263 string s1, string s2)
265 return test(cond1.CompareTo(cond2) == 0, file, line,
266 String.Format("[{0}] == [{1}]", s1, s2));
269 public static bool test_eq(object cond1, object cond2,
270 string file, int line,
271 string s1, string s2)
273 return test(cond1 == cond2, file, line,
274 String.Format("[{0}] == [{1}]", s1, s2));
277 public static bool test_ne(bool cond1, bool cond2,
278 string file, int line,
279 string s1, string s2)
281 return test(cond1 != cond2, file, line,
282 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
283 cond1, cond2, s1, s2));
286 public static bool test_ne(long cond1, long cond2,
287 string file, int line,
288 string s1, string s2)
290 return test(cond1 != cond2, file, line,
291 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
292 cond1, cond2, s1, s2));
295 public static bool test_ne(ulong cond1, ulong cond2,
296 string file, int line,
297 string s1, string s2)
299 return test(cond1 != cond2, file, line,
300 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
301 cond1, cond2, s1, s2));
304 public static bool test_ne(double cond1, double cond2,
305 string file, int line,
306 string s1, string s2)
308 return test(cond1 != cond2, file, line,
309 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
310 cond1, cond2, s1, s2));
313 public static bool test_ne(decimal cond1, decimal cond2,
314 string file, int line,
315 string s1, string s2)
317 return test(cond1 != cond2, file, line,
318 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
319 cond1, cond2, s1, s2));
322 public static bool test_ne(string cond1, string cond2,
323 string file, int line,
324 string s1, string s2)
326 return test(cond1 != cond2, file, line,
327 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
328 cond1, cond2, s1, s2));
331 // See notes for test_eq(IComparable,IComparable)
332 public static bool test_ne(IComparable cond1, IComparable cond2,
333 string file, int line,
334 string s1, string s2)
336 return test(cond1.CompareTo(cond2) != 0, file, line,
337 String.Format("[{0}] != [{1}]", s1, s2));
340 public static bool test_ne(object cond1, object cond2,
341 string file, int line,
342 string s1, string s2)
344 return test(cond1 != cond2, file, line,
345 String.Format("[{0}] != [{1}]", s1, s2));
349 public class WvAssertionFailure : Exception
351 public WvAssertionFailure()
356 public WvAssertionFailure(string msg)
362 // Placeholders for NUnit compatibility
363 public class TestFixtureAttribute : Attribute
366 public class TestAttribute : Attribute
369 [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
370 public class CategoryAttribute : Attribute
372 public CategoryAttribute(string x)