3 * Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
4 * See the included file named LICENSE for license information.
7 using System.Collections.Generic;
8 using System.Reflection;
9 using System.Runtime.Serialization;
12 // We put this in wvtest.cs since wvtest.cs should be able to compile all
13 // by itself, without relying on any other parts of wvdotnet. On the other
14 // hand, it's perfectly fine for wvdotnet to have wvtest.cs in it.
17 public static class WvReflection
19 public static IEnumerable<Type> find_types(Type attrtype)
21 foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
23 foreach (Type t in a.GetTypes())
25 if (!t.IsDefined(attrtype, false))
33 public static IEnumerable<MethodInfo> find_methods(this Type t,
36 foreach (MethodInfo m in t.GetMethods())
38 if (!m.IsDefined(attrtype, false))
56 public TestInfo(string name, Action cb)
57 { this.name = name; this.cb = cb; }
59 List<TestInfo> tests = new List<TestInfo>();
61 public int failures { get; private set; }
66 WvReflection.find_types(typeof(TestFixtureAttribute)))
68 foreach (MethodInfo m in
69 t.find_methods(typeof(TestAttribute)))
71 // The new t2, m2 are needed so that each delegate gets
72 // its own copy of the variable.
75 RegisterTest(String.Format("{0}/{1}",
79 m2.Invoke(Activator.CreateInstance(t2),
81 } catch (TargetInvocationException e) {
82 throw e.InnerException;
89 public void RegisterTest(string name, Action tc)
91 tests.Add(new TestInfo(name, tc));
94 public static void DoMain()
96 // Enough to run an entire test
97 Environment.Exit(new WvTest().Run());
102 string[] args = Environment.GetCommandLineArgs();
104 if (args.Length <= 1)
105 Console.WriteLine("WvTest: Running all tests");
107 Console.WriteLine("WvTest: Running only selected tests");
109 foreach (TestInfo test in tests)
111 string[] parts = test.name.Split(new char[] { '/' }, 2);
113 bool runthis = (args.Length <= 1);
114 foreach (string arg in args)
115 if (parts[0].StartsWith(arg) || parts[1].StartsWith(arg))
118 if (!runthis) continue;
120 Console.WriteLine("\nTesting \"{0}\" in {1}:",
125 } catch (WvAssertionFailure) {
127 } catch (Exception e) {
128 Console.WriteLine(e.ToString());
129 Console.WriteLine("! WvTest Exception received FAILED");
134 Console.Out.WriteLine("Result: {0} failures.", failures);
136 // Return a safe unix exit code
137 return failures > 0 ? 1 : 0;
140 public static bool booleanize(bool x)
145 public static bool booleanize(long x)
150 public static bool booleanize(ulong x)
155 public static bool booleanize(string s)
157 return s != null && s != "";
160 public static bool booleanize(object o)
165 static bool expect_fail = false;
166 public static void expect_next_failure()
171 public static bool test(bool ok, string file, int line, string s)
173 s = s.Replace("\n", "!");
174 s = s.Replace("\r", "!");
179 suffix = " (expected) ok";
181 suffix = " (expected fail!) FAILED";
183 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}{4}",
185 ok ? "ok" : "FAILED",
191 throw new WvAssertionFailure(String.Format("{0}:{1} {2}", file, line, s));
196 public static void test_exception(string file, int line, string s)
198 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}",
199 file, line, s, "EXCEPTION");
203 public static bool test_eq(bool cond1, bool cond2,
204 string file, int line,
205 string s1, string s2)
207 return test(cond1 == cond2, file, line,
208 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
209 cond1, cond2, s1, s2));
212 public static bool test_eq(long cond1, long cond2,
213 string file, int line,
214 string s1, string s2)
216 return test(cond1 == cond2, file, line,
217 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
218 cond1, cond2, s1, s2));
221 public static bool test_eq(ulong cond1, ulong cond2,
222 string file, int line,
223 string s1, string s2)
225 return test(cond1 == cond2, file, line,
226 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
227 cond1, cond2, s1, s2));
230 public static bool test_eq(double cond1, double cond2,
231 string file, int line,
232 string s1, string s2)
234 return test(cond1 == cond2, file, line,
235 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
236 cond1, cond2, s1, s2));
239 public static bool test_eq(decimal cond1, decimal cond2,
240 string file, int line,
241 string s1, string s2)
243 return test(cond1 == cond2, file, line,
244 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
245 cond1, cond2, s1, s2));
248 public static bool test_eq(string cond1, string cond2,
249 string file, int line,
250 string s1, string s2)
252 return test(cond1 == cond2, file, line,
253 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
254 cond1, cond2, s1, s2));
257 // some objects can compare themselves to 'null', which is helpful.
258 // for example, DateTime.MinValue == null, but only through
259 // IComparable, not through IObject.
260 public static bool test_eq(IComparable cond1, IComparable cond2,
261 string file, int line,
262 string s1, string s2)
264 return test(cond1.CompareTo(cond2) == 0, file, line,
265 String.Format("[{0}] == [{1}]", s1, s2));
268 public static bool test_eq(object cond1, object cond2,
269 string file, int line,
270 string s1, string s2)
272 return test(cond1 == cond2, file, line,
273 String.Format("[{0}] == [{1}]", s1, s2));
276 public static bool test_ne(bool cond1, bool cond2,
277 string file, int line,
278 string s1, string s2)
280 return test(cond1 != cond2, file, line,
281 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
282 cond1, cond2, s1, s2));
285 public static bool test_ne(long cond1, long cond2,
286 string file, int line,
287 string s1, string s2)
289 return test(cond1 != cond2, file, line,
290 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
291 cond1, cond2, s1, s2));
294 public static bool test_ne(ulong cond1, ulong cond2,
295 string file, int line,
296 string s1, string s2)
298 return test(cond1 != cond2, file, line,
299 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
300 cond1, cond2, s1, s2));
303 public static bool test_ne(double cond1, double cond2,
304 string file, int line,
305 string s1, string s2)
307 return test(cond1 != cond2, file, line,
308 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
309 cond1, cond2, s1, s2));
312 public static bool test_ne(decimal cond1, decimal cond2,
313 string file, int line,
314 string s1, string s2)
316 return test(cond1 != cond2, file, line,
317 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
318 cond1, cond2, s1, s2));
321 public static bool test_ne(string cond1, string cond2,
322 string file, int line,
323 string s1, string s2)
325 return test(cond1 != cond2, file, line,
326 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
327 cond1, cond2, s1, s2));
330 // See notes for test_eq(IComparable,IComparable)
331 public static bool test_ne(IComparable cond1, IComparable cond2,
332 string file, int line,
333 string s1, string s2)
335 return test(cond1.CompareTo(cond2) != 0, file, line,
336 String.Format("[{0}] != [{1}]", s1, s2));
339 public static bool test_ne(object cond1, object cond2,
340 string file, int line,
341 string s1, string s2)
343 return test(cond1 != cond2, file, line,
344 String.Format("[{0}] != [{1}]", s1, s2));
348 public class WvAssertionFailure : Exception
350 public WvAssertionFailure()
355 public WvAssertionFailure(string msg)
361 // Placeholders for NUnit compatibility
362 public class TestFixtureAttribute : Attribute
365 public class TestAttribute : Attribute
368 [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
369 public class CategoryAttribute : Attribute
371 public CategoryAttribute(string x)