3 * Copyright (C)2007-2012 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.
6 * You can get wvtest from: http://github.com/apenwarr/wvtest
9 using System.Collections.Generic;
10 using System.Reflection;
11 using System.Runtime.Serialization;
14 // We put this in wvtest.cs since wvtest.cs should be able to compile all
15 // by itself, without relying on any other parts of wvdotnet. On the other
16 // hand, it's perfectly fine for wvdotnet to have wvtest.cs in it.
19 public static class WvReflection
21 public static IEnumerable<Type> find_types(Type attrtype)
23 foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
25 foreach (Type t in a.GetTypes())
27 if (!t.IsDefined(attrtype, false))
35 public static IEnumerable<MethodInfo> find_methods(this Type t,
38 foreach (MethodInfo m in t.GetMethods())
40 if (!m.IsDefined(attrtype, false))
58 public TestInfo(string name, Action cb)
59 { this.name = name; this.cb = cb; }
61 List<TestInfo> tests = new List<TestInfo>();
63 public int failures { get; private set; }
68 WvReflection.find_types(typeof(TestFixtureAttribute)))
70 foreach (MethodInfo m in
71 t.find_methods(typeof(TestAttribute)))
73 // The new t2, m2 are needed so that each delegate gets
74 // its own copy of the variable.
77 RegisterTest(String.Format("{0}/{1}",
81 m2.Invoke(Activator.CreateInstance(t2),
83 } catch (TargetInvocationException e) {
84 throw e.InnerException;
91 public void RegisterTest(string name, Action tc)
93 tests.Add(new TestInfo(name, tc));
96 public static void DoMain()
98 // Enough to run an entire test
99 Environment.Exit(new WvTest().Run());
104 string[] args = Environment.GetCommandLineArgs();
106 if (args.Length <= 1)
107 Console.WriteLine("WvTest: Running all tests");
109 Console.WriteLine("WvTest: Running only selected tests");
111 foreach (TestInfo test in tests)
113 string[] parts = test.name.Split(new char[] { '/' }, 2);
115 bool runthis = (args.Length <= 1);
116 foreach (string arg in args)
117 if (parts[0].StartsWith(arg) || parts[1].StartsWith(arg))
120 if (!runthis) continue;
122 Console.WriteLine("\nTesting \"{0}\" in {1}:",
127 } catch (WvAssertionFailure) {
129 } catch (Exception e) {
130 Console.WriteLine(e.ToString());
131 Console.WriteLine("! WvTest Exception received FAILED");
136 Console.Out.WriteLine("Result: {0} failures.", failures);
138 // Return a safe unix exit code
139 return failures > 0 ? 1 : 0;
142 public static bool booleanize(bool x)
147 public static bool booleanize(long x)
152 public static bool booleanize(ulong x)
157 public static bool booleanize(string s)
159 return s != null && s != "";
162 public static bool booleanize(object o)
167 static bool expect_fail = false;
168 public static void expect_next_failure()
173 public static bool test(bool ok, string file, int line, string s)
175 s = s.Replace("\n", "!");
176 s = s.Replace("\r", "!");
181 suffix = " (expected) ok";
183 suffix = " (expected fail!) FAILED";
185 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}{4}",
187 ok ? "ok" : "FAILED",
193 throw new WvAssertionFailure(String.Format("{0}:{1} {2}", file, line, s));
198 public static void test_exception(string file, int line, string s)
200 Console.WriteLine("! {0}:{1,-5} {2,-40} {3}",
201 file, line, s, "EXCEPTION");
205 public static bool test_eq(bool cond1, bool cond2,
206 string file, int line,
207 string s1, string s2)
209 return test(cond1 == cond2, file, line,
210 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
211 cond1, cond2, s1, s2));
214 public static bool test_eq(long cond1, long cond2,
215 string file, int line,
216 string s1, string s2)
218 return test(cond1 == cond2, file, line,
219 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
220 cond1, cond2, s1, s2));
223 public static bool test_eq(ulong cond1, ulong cond2,
224 string file, int line,
225 string s1, string s2)
227 return test(cond1 == cond2, file, line,
228 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
229 cond1, cond2, s1, s2));
232 public static bool test_eq(double cond1, double cond2,
233 string file, int line,
234 string s1, string s2)
236 return test(cond1 == cond2, file, line,
237 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
238 cond1, cond2, s1, s2));
241 public static bool test_eq(decimal cond1, decimal cond2,
242 string file, int line,
243 string s1, string s2)
245 return test(cond1 == cond2, file, line,
246 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
247 cond1, cond2, s1, s2));
250 public static bool test_eq(string cond1, string cond2,
251 string file, int line,
252 string s1, string s2)
254 return test(cond1 == cond2, file, line,
255 String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})",
256 cond1, cond2, s1, s2));
259 // some objects can compare themselves to 'null', which is helpful.
260 // for example, DateTime.MinValue == null, but only through
261 // IComparable, not through IObject.
262 public static bool test_eq(IComparable cond1, IComparable cond2,
263 string file, int line,
264 string s1, string s2)
266 return test(cond1.CompareTo(cond2) == 0, file, line,
267 String.Format("[{0}] == [{1}]", s1, s2));
270 public static bool test_eq(object cond1, object cond2,
271 string file, int line,
272 string s1, string s2)
274 return test(cond1 == cond2, file, line,
275 String.Format("[{0}] == [{1}]", s1, s2));
278 public static bool test_ne(bool cond1, bool cond2,
279 string file, int line,
280 string s1, string s2)
282 return test(cond1 != cond2, file, line,
283 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
284 cond1, cond2, s1, s2));
287 public static bool test_ne(long cond1, long cond2,
288 string file, int line,
289 string s1, string s2)
291 return test(cond1 != cond2, file, line,
292 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
293 cond1, cond2, s1, s2));
296 public static bool test_ne(ulong cond1, ulong cond2,
297 string file, int line,
298 string s1, string s2)
300 return test(cond1 != cond2, file, line,
301 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
302 cond1, cond2, s1, s2));
305 public static bool test_ne(double cond1, double cond2,
306 string file, int line,
307 string s1, string s2)
309 return test(cond1 != cond2, file, line,
310 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
311 cond1, cond2, s1, s2));
314 public static bool test_ne(decimal cond1, decimal cond2,
315 string file, int line,
316 string s1, string s2)
318 return test(cond1 != cond2, file, line,
319 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
320 cond1, cond2, s1, s2));
323 public static bool test_ne(string cond1, string cond2,
324 string file, int line,
325 string s1, string s2)
327 return test(cond1 != cond2, file, line,
328 String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})",
329 cond1, cond2, s1, s2));
332 // See notes for test_eq(IComparable,IComparable)
333 public static bool test_ne(IComparable cond1, IComparable cond2,
334 string file, int line,
335 string s1, string s2)
337 return test(cond1.CompareTo(cond2) != 0, file, line,
338 String.Format("[{0}] != [{1}]", s1, s2));
341 public static bool test_ne(object cond1, object cond2,
342 string file, int line,
343 string s1, string s2)
345 return test(cond1 != cond2, file, line,
346 String.Format("[{0}] != [{1}]", s1, s2));
350 public class WvAssertionFailure : Exception
352 public WvAssertionFailure()
357 public WvAssertionFailure(string msg)
363 // Placeholders for NUnit compatibility
364 public class TestFixtureAttribute : Attribute
367 public class TestAttribute : Attribute
370 [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
371 public class CategoryAttribute : Attribute
373 public CategoryAttribute(string x)