]> rtime.felk.cvut.cz Git - wvtest.git/commitdiff
Import latest wvtest for C#/.NET from versaplex project.
authorAvery Pennarun <apenwarr@gmail.com>
Fri, 1 May 2009 00:42:44 +0000 (20:42 -0400)
committerAvery Pennarun <apenwarr@gmail.com>
Fri, 1 May 2009 01:09:44 +0000 (21:09 -0400)
Commit 8f939de8b03b0e0236a182543af0298bb6b97c52.

dotnet/monorules.mk [new file with mode: 0644]
dotnet/wvtest.cs [new file with mode: 0644]
dotnet/wvtest.cs.h [new file with mode: 0644]
dotnet/wvtest.t.cs [new file with mode: 0644]

diff --git a/dotnet/monorules.mk b/dotnet/monorules.mk
new file mode 100644 (file)
index 0000000..e066ec9
--- /dev/null
@@ -0,0 +1,83 @@
+default: all
+
+SHELL=/bin/bash
+
+# cc -E tries to guess by extension what to do with the file.
+# And it does other weird things. cpp seems to Just Work(tm), so use that for
+# our C# (.cs) files
+CSCPP=cpp
+
+# Cygwin supports symlinks, but they aren't actually useful outside cygwin,
+# so let's just copy instead.  We also use Microsoft's .net compiler instead
+# of mono.
+ifeq ($(OS),Windows_NT)
+  CSC?=csc
+  SYMLINK=cp
+  MONORUN=
+else
+  CSC?=gmcs -langversion:linq
+  SYMLINK=ln -sf
+  PKGS += /r:Mono.Posix
+  MONORUN=mono --debug
+endif
+
+CSFLAGS=/warn:4 /debug
+#CSFLAGS += /warnaserror
+
+TESTRUNNER=$(WVDOTNET)/wvtestrunner.pl
+
+# Rules for generating autodependencies on header files
+$(patsubst %.cs.E,%.d,$(filter %.cs.E,$(FILES))): %.d: %.cs
+       @echo Generating dependency file $@ for $<
+       @set -e; set -o pipefail; rm -f $@; (\
+           ($(CSCPP) -M -MM -MQ '$@' $(CPPFLAGS) $< && echo Makefile) \
+               | paste -s -d ' ' - && \
+           $(CSCPP) -M -MM -MQ '$<'.E $(CPPFLAGS) $< \
+       ) > $@ \
+       || (rm -f $@ && echo "Error generating dependency file." && exit 1)
+
+include $(patsubst %.cs.E,%.d,$(filter %.cs.E,$(FILES)))
+
+# Rule for actually preprocessing source files with headers
+%.cs.E: %.cs
+       @rm -f $@
+       set -o pipefail; $(CSCPP) $(CPPFLAGS) -C -dI $< \
+               | expand -8 \
+               | sed -e 's,^#include,//#include,' \
+               | grep -v '^# [0-9]' \
+               >$@ || (rm -f $@ && exit 1)
+
+
+define csbuild
+       @for d in $(filter ../%.dll,$^); do \
+               rm -f $$(basename $$d); \
+               $(SYMLINK) -v $$d .; \
+       done
+       $(CSC) $(CSFLAGS) /target:$1 /out:$@ \
+               $(PKGS) \
+               $(filter %.cs.E %.cs,$^) \
+               $(patsubst %.dll,/r:%.dll,$(filter %.dll,$^))
+endef
+
+
+%.dll: assemblyinfo.cs
+       $(call csbuild,library)
+
+# This must come before the %.cs rule, since %.cs.E files are better.
+%.exe: %.cs.E
+       $(call csbuild,exe)
+
+%.exe: %.cs
+       $(call csbuild,exe)
+
+%: %.exe
+       rm -f $@
+       $(SYMLINK) $< $@
+
+%.pass: %.exe
+       rm -f $@
+       $(TESTRUNNER) $(MONORUN) ./$^
+       touch $@
+
+clean::
+       rm -f *~ *.E *.d *.exe *.dll *.mdb *.pdb
diff --git a/dotnet/wvtest.cs b/dotnet/wvtest.cs
new file mode 100644 (file)
index 0000000..de1cb7a
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Versaplex:
+ *   Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
+ *       See the included file named LICENSE for license information.
+ */
+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)
+        {
+        }
+    }
+}
diff --git a/dotnet/wvtest.cs.h b/dotnet/wvtest.cs.h
new file mode 100644 (file)
index 0000000..30ce532
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef __WVTEST_CS_H // Blank lines in this file mess up line numbering!
+#define __WVTEST_CS_H
+#define WVASSERT(x) try { WvTest.test(WvTest.booleanize(x), __FILE__, __LINE__, #x); } catch (Wv.Test.WvAssertionFailure) { throw; } catch (System.Exception) { WvTest.test_exception(__FILE__, __LINE__, #x); throw; }
+#define WVPASS(x) WVASSERT(x)
+#define WVFAIL(x) try { WvTest.test(!WvTest.booleanize(x), __FILE__, __LINE__, "NOT(" + #x + ")"); } catch (Wv.Test.WvAssertionFailure) { throw; } catch (System.Exception) { WvTest.test_exception(__FILE__, __LINE__, "NOT(" + #x + ")"); throw; }
+#define WVEXCEPT(x) { System.Exception _wvex = null; try { x; } catch (System.Exception _wvasserte) { _wvex = _wvasserte; } WvTest.test(_wvex != null, __FILE__, __LINE__, "EXCEPT(" + #x + ")"); if (_wvex != null) throw _wvex; }
+#define WVPASSEQ(x, y) try { WvTest.test_eq((x), (y), __FILE__, __LINE__, #x, #y); } catch (Wv.Test.WvAssertionFailure) { throw; } catch (System.Exception) { WvTest.test_exception(__FILE__, __LINE__, string.Format("[{0}] == [{1}]", #x, #y)); throw; }
+#define WVPASSNE(x, y) try { WvTest.test_ne((x), (y), __FILE__, __LINE__, #x, #y); } catch (Wv.Test.WvAssertionFailure) { throw; } catch (System.Exception) { WvTest.test_exception(__FILE__, __LINE__, string.Format("[{0}] != [{1}]", #x, #y)); throw; }
+#endif // __WVTEST_CS_H
diff --git a/dotnet/wvtest.t.cs b/dotnet/wvtest.t.cs
new file mode 100644 (file)
index 0000000..6fd3c46
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Versaplex:
+ *   Copyright (C)2007-2008 Versabanq Innovations Inc. and contributors.
+ *       See the included file named LICENSE for license information.
+ */
+#include "wvtest.cs.h"
+using System;
+using Wv.Test;
+
+[TestFixture]
+public class WvTestTest
+{
+       [Test] public void test_wvtest()
+       {
+           WVPASS(1);
+           WVPASS("hello");
+           WVPASS(new Object());
+           WVPASS(0 != 1);
+           
+           WVFAIL(0);
+           WVFAIL("");
+           WVFAIL(null);
+           
+           WVPASSEQ(7, 7);
+           WVPASSEQ("foo", "foo");
+           WVPASSEQ("", "");
+           Object obj = new Object();
+           WVPASSEQ(obj, obj);
+           WVPASSEQ(null, null);
+           
+           WVPASSNE(7, 8);
+           WVPASSNE("foo", "blue");
+           WVPASSNE("", "notempty");
+           WVPASSNE(null, "");
+           WVPASSNE(obj, null);
+           WVPASSNE(obj, new Object());
+           WVPASSNE(new Object(), new Object());
+       }   
+    
+       // these are only public to get rid of the "not assigned to" warnings.
+       // we don't assign to them because that's the whole point of the test.
+       public DateTime null_date;
+       public TimeSpan null_span;
+       
+       [Test] public void test_dates_and_spans()
+       {
+           WVPASS(null_date == DateTime.MinValue);
+           WVPASSEQ(null_date, DateTime.MinValue);
+           WVPASS(null_span == TimeSpan.Zero);
+           WVPASSEQ(null_span, TimeSpan.Zero);
+           
+           TimeSpan t = TimeSpan.FromMinutes(60*24*7);
+           WVPASSEQ(t.ToString(), "7.00:00:00");
+           WVPASSEQ(t.Ticks, 7*24*60*60*10000000L);
+           WVPASS(t.TotalMinutes == 7*24*60);
+           WVPASSEQ(t.TotalMinutes, 7*24*60);
+           WVPASSEQ(t.TotalSeconds, 7*24*60*60);
+           WVPASSEQ(t.Minutes, 0);
+       }
+
+       void throw_exception()
+       {
+           throw new System.Exception("Exception thrown");
+       }
+       void no_throw_exception()
+       {
+           return;
+       }
+
+       [Test] public void test_exceptions()
+       {
+           bool caught = false;
+
+           try {
+               WVEXCEPT(throw_exception());
+           } catch (Wv.Test.WvAssertionFailure e) {
+               throw e;
+           } catch (System.Exception) {
+               caught = true;
+           }
+
+           WVPASS(caught);
+
+           caught = false;
+
+           System.Console.WriteLine("Ignore next failure: it is expected");
+           WvTest.expect_next_failure();
+           try {
+               WVEXCEPT(no_throw_exception());
+           } catch (Wv.Test.WvAssertionFailure) {
+               caught = true;
+           }
+
+           WVPASS(caught);
+       }
+}