2 // TestHelper.cs: Helper class for MWF unit tests.
5 // Everaldo Canuto (ecanuto@novell.com)
6 // Andreia Gaita (avidigal@novell.com)
8 // (C) 2006 Novell, Inc. (http://www.novell.com)
12 using System.ComponentModel;
13 using System.Windows.Forms;
15 using System.Reflection;
16 using System.Collections;
17 using NUnit.Framework;
19 using System.Diagnostics;
21 namespace MonoTests.System.Windows.Forms
23 public class TestHelper
26 protected virtual void SetUp ()
31 protected virtual void TearDown () {
32 int c = Application.OpenForms.Count;
34 Console.WriteLine ("HEY! You created " + c.ToString () + " form(s) and you didn't dispose of them!");
35 Console.WriteLine ("Please modify your test to shut me up.");
37 for (int i = Application.OpenForms.Count - 1; i >= 0; i--) {
38 Application.OpenForms[i].Dispose ();
44 public class FormWatcher : Form
47 public FormWatcher (int[] watches) : base () {
48 this.watches = watches;
50 protected override void WndProc (ref Message m)
52 foreach (int i in watches) {
53 if ((int)m.Msg == i) {
54 Console.WriteLine ((this.Name != "" && this.Name != null ? this.Name : "FormWatcher") + " received message " + m.ToString ());
62 public class ControlWatcher : Control
65 public ControlWatcher (int[] watches) : base () {
66 this.watches = watches;
68 protected override void WndProc (ref Message m)
70 foreach (int i in watches) {
71 if ((int)m.Msg == i) {
72 Console.WriteLine ((this.Name != "" && this.Name != null ? this.Name : "ControlWatcher") + " received message " + m.ToString ());
80 public class ButtonWatcher : Button
83 public ButtonWatcher (int[] watches) : base () {
84 this.watches = watches;
85 foreach (int i in this.watches) {
86 Console.WriteLine ("Listening to " + Enum.GetName (typeof(Msg), i));
90 protected override void WndProc (ref Message m)
92 foreach (int i in watches) {
93 if ((int)m.Msg == i) {
94 Console.WriteLine ((this.Name != "" && this.Name != null ? this.Name : "ButtonWatcher") + " received message " + m.ToString ());
102 public static void DumpObject (object obj, string objName)
104 DumpObject (obj, obj.GetType (), objName, "#", int.MaxValue);
107 public static void DumpObject (object obj, string objName, int maxrecursive)
109 DumpObject (obj, obj.GetType (), objName, "#", maxrecursive);
112 public static void DumpObject (object obj, Type objType, string objName, string prefix, int maxrecursive)
114 using (StringWriter writer = new StringWriter ()) {
115 DumpObject (obj, objType, objName, writer, 0, prefix, new ArrayList (), maxrecursive, 0);
116 Debug.WriteLine (writer.ToString ());
117 //return writer.ToString ();
121 public static void DumpObject (object obj, Type objType, string objName, StringWriter writer, int tabs, string prefix, ArrayList done, int maxrecursive, int level)
126 for (int j = 0; j < done.Count; j++) {
127 if (!(obj.GetType ().IsClass || obj.GetType ().IsInterface))
132 if (obj.GetType ().IsClass || obj.GetType ().IsInterface)
136 PropertyInfo [] properties = objType.GetProperties (BindingFlags.Public | BindingFlags.Instance);
137 FieldInfo [] fields = objType.GetFields (BindingFlags.Public | BindingFlags.Instance);
139 Hashtable values = new Hashtable ();
140 Hashtable members = new Hashtable ();
142 foreach (PropertyInfo property in properties) {
146 getter = property.GetGetMethod ();
151 if (getter.GetParameters ().Length > 0)
155 value = getter.Invoke (obj, new object [] {});
156 } catch (TargetInvocationException ex) {
157 if (ex.InnerException != null) {
158 value = ex.InnerException;
162 } catch (Exception ex) {
165 members.Add (property.Name, property);
166 values.Add (property.Name, value);
169 foreach (FieldInfo field in fields) {
173 value = field.GetValue (obj);
174 } catch (TargetInvocationException ex) {
175 if (ex.InnerException != null) {
176 value = ex.InnerException;
180 } catch (Exception ex) {
184 members.Add (field.Name, field);
185 values.Add (field.Name, value);
188 string [] sorted = new string [values.Count];
190 foreach (DictionaryEntry entry in values) {
191 sorted [i++] = (string) entry.Key;
195 string showName = objName;
196 for (int j = 0; j < sorted.Length; j++) {
197 string name = sorted [j];
198 object value = values [name];
199 string message = prefix + showName + "." + name;
200 string tab = new string ('\t', tabs);
203 writer.WriteLine ("{0}Assert.IsNull ({1}.{2}, \"{3}\");", tab, showName, name, message);
209 switch (Type.GetTypeCode (value.GetType ())) {
210 case TypeCode.Boolean:
211 code = ((bool) value) ? "true" : "false"; break;
213 case TypeCode.Decimal:
214 case TypeCode.Double:
219 case TypeCode.Single:
220 case TypeCode.UInt16:
221 case TypeCode.UInt32:
222 case TypeCode.UInt64:
223 if (value.GetType ().IsEnum) {
224 string [] flags = value.ToString ().Split (',');
225 for (int k = 0; k < flags.Length; k++)
226 flags [k] = value.GetType ().Name + "." + flags [k].Trim ();
227 code = string.Join (" | ", flags);
229 code = value.ToString ();
233 code = "'" + ((char) value).ToString () + "'"; break;
234 case TypeCode.DateTime:
235 code = "new System.DateTime (" + ((DateTime) value).Ticks + ")"; break;
236 case TypeCode.DBNull:
237 code = "System.DBNull.Value" ; break;
238 case TypeCode.Object:
240 if (value is Exception) {
241 writer.WriteLine (tab + "try {");
242 writer.WriteLine (tab + "\tobject zxf = {0}.{1};", showName, name);
243 writer.WriteLine (tab + "\tTestHelper.RemoveWarning (zxf);");
244 writer.WriteLine (tab + "\tAssert.Fail (\"Expected '{0}', but no exception was thrown.\", \"{1}\");", value.GetType ().FullName, message);
245 writer.WriteLine (tab + "}} catch ({0} ex) {{", value.GetType ().Name);
246 writer.WriteLine (tab + "\tAssert.AreEqual (@\"{0}\", ex.Message);", ((Exception) value).Message.Replace ("\"", "\"\""));
247 writer.WriteLine (tab + "} catch (Exception ex) {");
248 writer.WriteLine (tab + "\tAssert.Fail (\"Expected '{0}', got '\" + ex.GetType ().FullName + \"'.\", \"{1}\");", value.GetType ().FullName, message);
249 writer.WriteLine (tab + "}");
251 if (maxrecursive > level) {
252 DumpObject (value, ((MemberInfo)members [name]).DeclaringType, showName + "." + name, writer, tabs, prefix, done, maxrecursive, level + 1);
254 writer.WriteLine ("{0}Assert.IsNotNull ({1}.{2}, \"{3}\");", tab, showName, name, message);
258 case TypeCode.String:
259 code = "@\"" + ((string) value).Replace ("\"", "\"\"") + "\""; break;
266 writer.WriteLine ("{0}Assert.AreEqual ({4}, {1}.{2}, \"{3}\");", tab, showName, name, message, code);
274 public static void RemoveWarning (params object [] param)
276 // Call this function with the unused variable as the parameter.
279 public static CreateParams GetCreateParams (Control control)
281 CreateParams cp = (CreateParams) control.GetType().GetProperty("CreateParams", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(control, null);
285 public static bool IsStyleSet (Control control, WindowStyles style) {
286 CreateParams cp = GetCreateParams (control);
287 return ((cp.Style & (int) style) == (int) style);
290 public static bool IsExStyleSet (Control control, WindowExStyles style) {
291 CreateParams cp = GetCreateParams (control);
292 return ((cp.ExStyle & (int) style) == (int) style);
295 public static bool RunningOnUnix {
297 // check for Unix platforms - see FAQ for more details
298 // http://www.mono-project.com/FAQ:_Technical#How_to_detect_the_execution_platform_.3F
299 int platform = (int) Environment.OSVersion.Platform;
300 return ((platform == 4) || (platform == 128) || (platform == 6));
306 public enum WindowStyles : int {
307 WS_OVERLAPPED = 0x00000000,
308 WS_POPUP = unchecked((int)0x80000000),
309 WS_CHILD = 0x40000000,
310 WS_MINIMIZE = 0x20000000,
311 WS_VISIBLE = 0x10000000,
312 WS_DISABLED = 0x08000000,
313 WS_CLIPSIBLINGS = 0x04000000,
314 WS_CLIPCHILDREN = 0x02000000,
315 WS_MAXIMIZE = 0x01000000,
316 WS_CAPTION = 0x00C00000,
317 WS_BORDER = 0x00800000,
318 WS_DLGFRAME = 0x00400000,
319 WS_VSCROLL = 0x00200000,
320 WS_HSCROLL = 0x00100000,
321 WS_SYSMENU = 0x00080000,
322 WS_THICKFRAME = 0x00040000,
323 WS_GROUP = 0x00020000,
324 WS_TABSTOP = 0x00010000,
325 WS_MINIMIZEBOX = 0x00020000,
326 WS_MAXIMIZEBOX = 0x00010000,
327 WS_TILED = 0x00000000,
328 WS_ICONIC = 0x20000000,
329 WS_SIZEBOX = 0x00040000,
330 WS_POPUPWINDOW = unchecked((int)0x80880000),
331 WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
332 WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
333 WS_CHILDWINDOW = WS_CHILD
337 public enum WindowExStyles : int {
339 WS_EX_DLGMODALFRAME = 0x00000001,
340 WS_EX_DRAGDETECT = 0x00000002,
341 WS_EX_NOPARENTNOTIFY = 0x00000004,
342 WS_EX_TOPMOST = 0x00000008,
343 WS_EX_ACCEPTFILES = 0x00000010,
344 WS_EX_TRANSPARENT = 0x00000020,
346 WS_EX_MDICHILD = 0x00000040,
347 WS_EX_TOOLWINDOW = 0x00000080,
348 WS_EX_WINDOWEDGE = 0x00000100,
349 WS_EX_CLIENTEDGE = 0x00000200,
350 WS_EX_CONTEXTHELP = 0x00000400,
352 WS_EX_RIGHT = 0x00001000,
353 WS_EX_LEFT = 0x00000000,
354 WS_EX_RTLREADING = 0x00002000,
355 WS_EX_LTRREADING = 0x00000000,
356 WS_EX_LEFTSCROLLBAR = 0x00004000,
357 WS_EX_LAYERED = 0x00080000,
358 WS_EX_RIGHTSCROLLBAR = 0x00000000,
360 WS_EX_CONTROLPARENT = 0x00010000,
361 WS_EX_STATICEDGE = 0x00020000,
362 WS_EX_APPWINDOW = 0x00040000,
363 WS_EX_NOINHERITLAYOUT = 0x00100000,
364 WS_EX_LAYOUTRTL = 0x00400000,
365 WS_EX_COMPOSITED = 0x02000000,
366 WS_EX_NOACTIVATE = 0x08000000,
368 WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE,
369 WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST
378 WM_ACTIVATE = 0x0006,
379 WM_SETFOCUS = 0x0007,
380 WM_KILLFOCUS = 0x0008,
381 // public const uint WM_SETVISIBLE = 0x0009;
383 WM_SETREDRAW = 0x000B,
386 WM_GETTEXTLENGTH = 0x000E,
389 WM_QUERYENDSESSION = 0x0011,
391 WM_QUERYOPEN = 0x0013,
392 WM_ERASEBKGND = 0x0014,
393 WM_SYSCOLORCHANGE = 0x0015,
394 WM_ENDSESSION = 0x0016,
395 // public const uint WM_SYSTEMERROR = 0x0017;
396 WM_SHOWWINDOW = 0x0018,
397 WM_CTLCOLOR = 0x0019,
398 WM_WININICHANGE = 0x001A,
399 WM_SETTINGCHANGE = 0x001A,
400 WM_DEVMODECHANGE = 0x001B,
401 WM_ACTIVATEAPP = 0x001C,
402 WM_FONTCHANGE = 0x001D,
403 WM_TIMECHANGE = 0x001E,
404 WM_CANCELMODE = 0x001F,
405 WM_SETCURSOR = 0x0020,
406 WM_MOUSEACTIVATE = 0x0021,
407 WM_CHILDACTIVATE = 0x0022,
408 WM_QUEUESYNC = 0x0023,
409 WM_GETMINMAXINFO = 0x0024,
410 WM_PAINTICON = 0x0026,
411 WM_ICONERASEBKGND = 0x0027,
412 WM_NEXTDLGCTL = 0x0028,
413 // public const uint WM_ALTTABACTIVE = 0x0029;
414 WM_SPOOLERSTATUS = 0x002A,
415 WM_DRAWITEM = 0x002B,
416 WM_MEASUREITEM = 0x002C,
417 WM_DELETEITEM = 0x002D,
418 WM_VKEYTOITEM = 0x002E,
419 WM_CHARTOITEM = 0x002F,
422 WM_SETHOTKEY = 0x0032,
423 WM_GETHOTKEY = 0x0033,
424 // public const uint WM_FILESYSCHANGE = 0x0034;
425 // public const uint WM_ISACTIVEICON = 0x0035;
426 // public const uint WM_QUERYPARKICON = 0x0036;
427 WM_QUERYDRAGICON = 0x0037,
428 WM_COMPAREITEM = 0x0039,
429 // public const uint WM_TESTING = 0x003a;
430 // public const uint WM_OTHERWINDOWCREATED = 0x003c;
431 WM_GETOBJECT = 0x003D,
432 // public const uint WM_ACTIVATESHELLWINDOW = 0x003e;
433 WM_COMPACTING = 0x0041,
434 WM_COMMNOTIFY = 0x0044 ,
435 WM_WINDOWPOSCHANGING = 0x0046,
436 WM_WINDOWPOSCHANGED = 0x0047,
438 WM_COPYDATA = 0x004A,
439 WM_CANCELJOURNAL = 0x004B,
441 WM_INPUTLANGCHANGEREQUEST = 0x0050,
442 WM_INPUTLANGCHANGE = 0x0051,
445 WM_USERCHANGED = 0x0054,
446 WM_NOTIFYFORMAT = 0x0055,
447 WM_CONTEXTMENU = 0x007B,
448 WM_STYLECHANGING = 0x007C,
449 WM_STYLECHANGED = 0x007D,
450 WM_DISPLAYCHANGE = 0x007E,
453 // Non-Client messages
455 WM_NCCREATE = 0x0081,
456 WM_NCDESTROY = 0x0082,
457 WM_NCCALCSIZE = 0x0083,
458 WM_NCHITTEST = 0x0084,
460 WM_NCACTIVATE = 0x0086,
461 WM_GETDLGCODE = 0x0087,
462 WM_SYNCPAINT = 0x0088,
463 // public const uint WM_SYNCTASK = 0x0089;
464 WM_NCMOUSEMOVE = 0x00A0,
465 WM_NCLBUTTONDOWN = 0x00A1,
466 WM_NCLBUTTONUP = 0x00A2,
467 WM_NCLBUTTONDBLCLK = 0x00A3,
468 WM_NCRBUTTONDOWN = 0x00A4,
469 WM_NCRBUTTONUP = 0x00A5,
470 WM_NCRBUTTONDBLCLK = 0x00A6,
471 WM_NCMBUTTONDOWN = 0x00A7,
472 WM_NCMBUTTONUP = 0x00A8,
473 WM_NCMBUTTONDBLCLK = 0x00A9,
474 // public const uint WM_NCXBUTTONDOWN = 0x00ab;
475 // public const uint WM_NCXBUTTONUP = 0x00ac;
476 // public const uint WM_NCXBUTTONDBLCLK = 0x00ad;
478 WM_KEYFIRST = 0x0100,
481 WM_DEADCHAR = 0x0103,
482 WM_SYSKEYDOWN = 0x0104,
483 WM_SYSKEYUP = 0x0105,
485 WM_SYSDEADCHAR = 0x0107,
487 WM_IME_STARTCOMPOSITION = 0x010D,
488 WM_IME_ENDCOMPOSITION = 0x010E,
489 WM_IME_COMPOSITION = 0x010F,
490 WM_IME_KEYLAST = 0x010F,
491 WM_INITDIALOG = 0x0110,
493 WM_SYSCOMMAND = 0x0112,
497 WM_INITMENU = 0x0116,
498 WM_INITMENUPOPUP = 0x0117,
499 // public const uint WM_SYSTIMER = 0x0118;
500 WM_MENUSELECT = 0x011F,
501 WM_MENUCHAR = 0x0120,
502 WM_ENTERIDLE = 0x0121,
503 WM_MENURBUTTONUP = 0x0122,
504 WM_MENUDRAG = 0x0123,
505 WM_MENUGETOBJECT = 0x0124,
506 WM_UNINITMENUPOPUP = 0x0125,
507 WM_MENUCOMMAND = 0x0126,
508 // public const uint WM_CHANGEUISTATE = 0x0127;
509 // public const uint WM_UPDATEUISTATE = 0x0128;
510 // public const uint WM_QUERYUISTATE = 0x0129;
512 // public const uint WM_LBTRACKPOINT = 0x0131;
513 WM_CTLCOLORMSGBOX = 0x0132,
514 WM_CTLCOLOREDIT = 0x0133,
515 WM_CTLCOLORLISTBOX = 0x0134,
516 WM_CTLCOLORBTN = 0x0135,
517 WM_CTLCOLORDLG = 0x0136,
518 WM_CTLCOLORSCROLLBAR = 0x0137,
519 WM_CTLCOLORSTATIC = 0x0138,
520 WM_MOUSEMOVE = 0x0200,
521 WM_MOUSEFIRST = 0x0200,
522 WM_LBUTTONDOWN = 0x0201,
523 WM_LBUTTONUP = 0x0202,
524 WM_LBUTTONDBLCLK = 0x0203,
525 WM_RBUTTONDOWN = 0x0204,
526 WM_RBUTTONUP = 0x0205,
527 WM_RBUTTONDBLCLK = 0x0206,
528 WM_MBUTTONDOWN = 0x0207,
529 WM_MBUTTONUP = 0x0208,
530 WM_MBUTTONDBLCLK = 0x0209,
531 WM_MOUSEWHEEL = 0x020A,
532 WM_MOUSELAST = 0x020D,
533 // public const uint WM_XBUTTONDOWN = 0x020B;
534 // public const uint WM_XBUTTONUP = 0x020C;
535 // public const uint WM_XBUTTONDBLCLK = 0x020D;
536 WM_PARENTNOTIFY = 0x0210,
537 WM_ENTERMENULOOP = 0x0211,
538 WM_EXITMENULOOP = 0x0212,
539 WM_NEXTMENU = 0x0213,
541 WM_CAPTURECHANGED = 0x0215,
543 // public const uint WM_POWERBROADCAST = 0x0218;
544 WM_DEVICECHANGE = 0x0219,
545 WM_MDICREATE = 0x0220,
546 WM_MDIDESTROY = 0x0221,
547 WM_MDIACTIVATE = 0x0222,
548 WM_MDIRESTORE = 0x0223,
550 WM_MDIMAXIMIZE = 0x0225,
552 WM_MDICASCADE = 0x0227,
553 WM_MDIICONARRANGE = 0x0228,
554 WM_MDIGETACTIVE = 0x0229,
556 // public const uint WM_DROPOBJECT = 0x022A;
557 // public const uint WM_QUERYDROPOBJECT = 0x022B;
558 // public const uint WM_BEGINDRAG = 0x022C;
559 // public const uint WM_DRAGLOOP = 0x022D;
560 // public const uint WM_DRAGSELECT = 0x022E;
561 // public const uint WM_DRAGMOVE = 0x022F;
562 WM_MDISETMENU = 0x0230,
563 WM_ENTERSIZEMOVE = 0x0231,
564 WM_EXITSIZEMOVE = 0x0232,
565 WM_DROPFILES = 0x0233,
566 WM_MDIREFRESHMENU = 0x0234,
567 WM_IME_SETCONTEXT = 0x0281,
568 WM_IME_NOTIFY = 0x0282,
569 WM_IME_CONTROL = 0x0283,
570 WM_IME_COMPOSITIONFULL = 0x0284,
571 WM_IME_SELECT = 0x0285,
572 WM_IME_CHAR = 0x0286,
573 WM_IME_REQUEST = 0x0288,
574 WM_IME_KEYDOWN = 0x0290,
575 WM_IME_KEYUP = 0x0291,
576 WM_NCMOUSEHOVER = 0x02A0,
577 WM_MOUSEHOVER = 0x02A1,
578 WM_NCMOUSELEAVE = 0x02A2,
579 WM_MOUSELEAVE = 0x02A3,
585 WM_RENDERFORMAT = 0x0305,
586 WM_RENDERALLFORMATS = 0x0306,
587 WM_DESTROYCLIPBOARD = 0x0307,
588 WM_DRAWCLIPBOARD = 0x0308,
589 WM_PAINTCLIPBOARD = 0x0309,
590 WM_VSCROLLCLIPBOARD = 0x030A,
591 WM_SIZECLIPBOARD = 0x030B,
592 WM_ASKCBFORMATNAME = 0x030C,
593 WM_CHANGECBCHAIN = 0x030D,
594 WM_HSCROLLCLIPBOARD = 0x030E,
595 WM_QUERYNEWPALETTE = 0x030F,
596 WM_PALETTEISCHANGING = 0x0310,
597 WM_PALETTECHANGED = 0x0311,
600 WM_PRINTCLIENT = 0x0318,
601 WM_HANDHELDFIRST = 0x0358,
602 WM_HANDHELDLAST = 0x035F,
603 WM_AFXFIRST = 0x0360,
605 WM_PENWINFIRST = 0x0380,
606 WM_PENWINLAST = 0x038F,
610 // Our "private" ones
611 WM_MOUSE_ENTER = 0x0401,
612 WM_ASYNC_MESSAGE = 0x0403,
613 WM_REFLECT = WM_USER + 0x1c00,
614 WM_CLOSE_INTERNAL = WM_USER + 0x1c01