| /* |
| * WvTest: |
| * Copyright (C)2007-2012 Versabanq Innovations Inc. and contributors. |
| * Licensed under the GNU Library General Public License, version 2. |
| * See the included file named LICENSE for license information. |
| * You can get wvtest from: http://github.com/apenwarr/wvtest |
| */ |
| using System; |
| using System.Collections.Generic; |
| using System.Reflection; |
| using System.Runtime.Serialization; |
| using Wv; |
| |
| // We put this in wvtest.cs since wvtest.cs should be able to compile all |
| // by itself, without relying on any other parts of wvdotnet. On the other |
| // hand, it's perfectly fine for wvdotnet to have wvtest.cs in it. |
| namespace Wv |
| { |
| public static class WvReflection |
| { |
| public static IEnumerable<Type> find_types(Type attrtype) |
| { |
| foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) |
| { |
| foreach (Type t in a.GetTypes()) |
| { |
| if (!t.IsDefined(attrtype, false)) |
| continue; |
| |
| yield return t; |
| } |
| } |
| } |
| |
| public static IEnumerable<MethodInfo> find_methods(this Type t, |
| Type attrtype) |
| { |
| foreach (MethodInfo m in t.GetMethods()) |
| { |
| if (!m.IsDefined(attrtype, false)) |
| continue; |
| |
| yield return m; |
| } |
| } |
| } |
| } |
| |
| namespace Wv.Test |
| { |
| public class WvTest |
| { |
| struct TestInfo |
| { |
| public string name; |
| public Action cb; |
| |
| public TestInfo(string name, Action cb) |
| { this.name = name; this.cb = cb; } |
| } |
| List<TestInfo> tests = new List<TestInfo>(); |
| |
| public int failures { get; private set; } |
| |
| public WvTest() |
| { |
| foreach (Type t in |
| WvReflection.find_types(typeof(TestFixtureAttribute))) |
| { |
| foreach (MethodInfo m in |
| t.find_methods(typeof(TestAttribute))) |
| { |
| // The new t2, m2 are needed so that each delegate gets |
| // its own copy of the variable. |
| Type t2 = t; |
| MethodInfo m2 = m; |
| RegisterTest(String.Format("{0}/{1}", |
| t.Name, m.Name), |
| delegate() { |
| try { |
| m2.Invoke(Activator.CreateInstance(t2), |
| null); |
| } catch (TargetInvocationException e) { |
| throw e.InnerException; |
| } |
| }); |
| } |
| } |
| } |
| |
| public void RegisterTest(string name, Action tc) |
| { |
| tests.Add(new TestInfo(name, tc)); |
| } |
| |
| public static void DoMain() |
| { |
| // Enough to run an entire test |
| Environment.Exit(new WvTest().Run()); |
| } |
| |
| public int Run() |
| { |
| string[] args = Environment.GetCommandLineArgs(); |
| |
| if (args.Length <= 1) |
| Console.WriteLine("WvTest: Running all tests"); |
| else |
| Console.WriteLine("WvTest: Running only selected tests"); |
| |
| foreach (TestInfo test in tests) |
| { |
| string[] parts = test.name.Split(new char[] { '/' }, 2); |
| |
| bool runthis = (args.Length <= 1); |
| foreach (string arg in args) |
| if (parts[0].StartsWith(arg) || parts[1].StartsWith(arg)) |
| runthis = true; |
| |
| if (!runthis) continue; |
| |
| Console.WriteLine("\nTesting \"{0}\" in {1}:", |
| parts[1], parts[0]); |
| |
| try { |
| test.cb(); |
| } catch (WvAssertionFailure) { |
| failures++; |
| } catch (Exception e) { |
| Console.WriteLine(e.ToString()); |
| Console.WriteLine("! WvTest Exception received FAILED"); |
| failures++; |
| } |
| } |
| |
| Console.Out.WriteLine("Result: {0} failures.", failures); |
| |
| // Return a safe unix exit code |
| return failures > 0 ? 1 : 0; |
| } |
| |
| public static bool booleanize(bool x) |
| { |
| return x; |
| } |
| |
| public static bool booleanize(long x) |
| { |
| return x != 0; |
| } |
| |
| public static bool booleanize(ulong x) |
| { |
| return x != 0; |
| } |
| |
| public static bool booleanize(string s) |
| { |
| return s != null && s != ""; |
| } |
| |
| public static bool booleanize(object o) |
| { |
| return o != null; |
| } |
| |
| static bool expect_fail = false; |
| public static void expect_next_failure() |
| { |
| expect_fail = true; |
| } |
| |
| public static bool test(bool ok, string file, int line, string s) |
| { |
| s = s.Replace("\n", "!"); |
| s = s.Replace("\r", "!"); |
| string suffix = ""; |
| if (expect_fail) |
| { |
| if (!ok) |
| suffix = " (expected) ok"; |
| else |
| suffix = " (expected fail!) FAILED"; |
| } |
| Console.WriteLine("! {0}:{1,-5} {2,-40} {3}{4}", |
| file, line, s, |
| ok ? "ok" : "FAILED", |
| suffix); |
| Console.Out.Flush(); |
| expect_fail = false; |
| |
| if (!ok) |
| throw new WvAssertionFailure(String.Format("{0}:{1} {2}", file, line, s)); |
| |
| return ok; |
| } |
| |
| public static void test_exception(string file, int line, string s) |
| { |
| Console.WriteLine("! {0}:{1,-5} {2,-40} {3}", |
| file, line, s, "EXCEPTION"); |
| Console.Out.Flush(); |
| } |
| |
| public static bool test_eq(bool cond1, bool cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_eq(long cond1, long cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_eq(ulong cond1, ulong cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_eq(double cond1, double cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_eq(decimal cond1, decimal cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_eq(string cond1, string cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}] ({{{2}}} == {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| // some objects can compare themselves to 'null', which is helpful. |
| // for example, DateTime.MinValue == null, but only through |
| // IComparable, not through IObject. |
| public static bool test_eq(IComparable cond1, IComparable cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1.CompareTo(cond2) == 0, file, line, |
| String.Format("[{0}] == [{1}]", s1, s2)); |
| } |
| |
| public static bool test_eq(object cond1, object cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 == cond2, file, line, |
| String.Format("[{0}] == [{1}]", s1, s2)); |
| } |
| |
| public static bool test_ne(bool cond1, bool cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_ne(long cond1, long cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_ne(ulong cond1, ulong cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_ne(double cond1, double cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_ne(decimal cond1, decimal cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| public static bool test_ne(string cond1, string cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}] ({{{2}}} != {{{3}}})", |
| cond1, cond2, s1, s2)); |
| } |
| |
| // See notes for test_eq(IComparable,IComparable) |
| public static bool test_ne(IComparable cond1, IComparable cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1.CompareTo(cond2) != 0, file, line, |
| String.Format("[{0}] != [{1}]", s1, s2)); |
| } |
| |
| public static bool test_ne(object cond1, object cond2, |
| string file, int line, |
| string s1, string s2) |
| { |
| return test(cond1 != cond2, file, line, |
| String.Format("[{0}] != [{1}]", s1, s2)); |
| } |
| } |
| |
| public class WvAssertionFailure : Exception |
| { |
| public WvAssertionFailure() |
| : base() |
| { |
| } |
| |
| public WvAssertionFailure(string msg) |
| : base(msg) |
| { |
| } |
| } |
| |
| // Placeholders for NUnit compatibility |
| public class TestFixtureAttribute : Attribute |
| { |
| } |
| public class TestAttribute : Attribute |
| { |
| } |
| [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)] |
| public class CategoryAttribute : Attribute |
| { |
| public CategoryAttribute(string x) |
| { |
| } |
| } |
| } |