ReactOS  0.4.14-dev-583-g2a1ba2c
msg.h
Go to the documentation of this file.
1 /* Message Sequence Testing Code
2  *
3  * Copyright (C) 2007 James Hawkins
4  * Copyright (C) 2007 Lei Zhang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #pragma once
22 
23 #include <assert.h>
24 #include <windows.h>
25 #include "wine/heap.h"
26 #include "wine/test.h"
27 
28 /* undocumented SWP flags - from SDK 3.1 */
29 #define SWP_NOCLIENTSIZE 0x0800
30 #define SWP_NOCLIENTMOVE 0x1000
31 
32 typedef enum
33 {
34  sent = 0x1,
35  posted = 0x2,
36  parent = 0x4,
37  wparam = 0x8,
38  lparam = 0x10,
39  defwinproc = 0x20,
40  beginpaint = 0x40,
41  optional = 0x80,
42  hook = 0x100,
43  winevent_hook =0x200,
44  id = 0x400,
45  custdraw = 0x800
46 } msg_flags_t;
47 
48 struct message
49 {
50  UINT message; /* the WM_* code */
51  msg_flags_t flags; /* message props */
52  WPARAM wParam; /* expected value of wParam */
53  LPARAM lParam; /* expected value of lParam */
54  UINT id; /* extra message data: id of the window,
55  notify code etc. */
56  DWORD stage; /* custom draw stage */
57 };
58 
60 {
61  int count;
62  int size;
63  struct message *sequence;
64 };
65 
66 static void add_message(struct msg_sequence **seq, int sequence_index,
67  const struct message *msg)
68 {
69  struct msg_sequence *msg_seq = seq[sequence_index];
70 
71  if (!msg_seq->sequence)
72  {
73  msg_seq->size = 10;
74  msg_seq->sequence = heap_alloc(msg_seq->size * sizeof (*msg_seq->sequence));
75  }
76 
77  if (msg_seq->count == msg_seq->size)
78  {
79  msg_seq->size *= 2;
80  msg_seq->sequence = heap_realloc(msg_seq->sequence, msg_seq->size * sizeof (*msg_seq->sequence));
81  }
82 
83  assert(msg_seq->sequence);
84 
85  msg_seq->sequence[msg_seq->count] = *msg;
86  msg_seq->count++;
87 }
88 
89 static inline void flush_sequence(struct msg_sequence **seg, int sequence_index)
90 {
91  struct msg_sequence *msg_seq = seg[sequence_index];
92  heap_free(msg_seq->sequence);
93  msg_seq->sequence = NULL;
94  msg_seq->count = msg_seq->size = 0;
95 }
96 
97 static inline void flush_sequences(struct msg_sequence **seq, int n)
98 {
99  int i;
100 
101  for (i = 0; i < n; i++)
102  flush_sequence(seq, i);
103 }
104 
105 static void dump_sequence( struct msg_sequence **seq, int sequence_index,
106  const struct message *expected, const char *context,
107  const char *file, int line )
108 {
109  struct msg_sequence *msg_seq = seq[sequence_index];
110  const struct message *actual, *sequence;
111  unsigned int count = 0;
112 
113  sequence = msg_seq->sequence;
114  actual = sequence;
115 
116  trace_(file, line)("Failed sequence %s:\n", context );
117  while (expected->message && actual->message)
118  {
119  trace_(file, line)( " %u: expected: %04x - actual: %04x wp %08lx lp %08lx\n",
120  count, expected->message, actual->message, actual->wParam, actual->lParam );
121 
122  if (expected->message == actual->message)
123  {
124  if ((expected->flags & defwinproc) != (actual->flags & defwinproc) &&
125  (expected->flags & optional))
126  {
127  /* don't match messages if their defwinproc status differs */
128  expected++;
129  }
130  else
131  {
132  expected++;
133  actual++;
134  }
135  }
136  else
137  {
138  expected++;
139  actual++;
140  }
141  count++;
142  }
143 
144  /* optional trailing messages */
145  while (expected->message && expected->flags & optional)
146  {
147  trace_(file, line)( " %u: expected: msg %04x - actual: nothing\n", count, expected->message );
148  expected++;
149  count++;
150  }
151 
152  if (expected->message)
153  {
154  trace_(file, line)( " %u: expected: msg %04x - actual: nothing\n", count, expected->message );
155  return;
156  }
157 
158  while (actual->message)
159  {
160  trace_(file, line)( " %u: expected: nothing - actual: %04x wp %08lx lp %08lx\n",
161  count, actual->message, actual->wParam, actual->lParam );
162  actual++;
163  count++;
164  }
165 }
166 
167 static inline void ok_sequence_(struct msg_sequence **seq, int sequence_index,
168  const struct message *expected_list, const char *context, BOOL todo,
169  const char *file, int line)
170 {
171  static const struct message end_of_sequence = {0, 0, 0, 0};
172  struct msg_sequence *msg_seq = seq[sequence_index];
173  const struct message *expected = expected_list;
174  const struct message *actual, *sequence;
175  int failcount = 0, dump = 0;
176 
177  add_message(seq, sequence_index, &end_of_sequence);
178 
179  sequence = msg_seq->sequence;
180  actual = sequence;
181 
182  while (expected->message && actual->message)
183  {
184  if (expected->message == actual->message)
185  {
186  if (expected->flags & wparam)
187  {
188  if (expected->wParam != actual->wParam && todo)
189  {
190  todo_wine
191  {
192  failcount++;
193  dump++;
194  ok_(file, line) (FALSE,
195  "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
196  context, expected->message, expected->wParam, actual->wParam);
197  }
198  }
199  else
200  {
201  ok_(file, line) (expected->wParam == actual->wParam,
202  "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
203  context, expected->message, expected->wParam, actual->wParam);
204  if (expected->wParam != actual->wParam) dump++;
205  }
206  }
207 
208  if (expected->flags & lparam)
209  {
210  if (expected->lParam != actual->lParam && todo)
211  {
212  todo_wine
213  {
214  failcount++;
215  dump++;
216  ok_(file, line) (FALSE,
217  "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
218  context, expected->message, expected->lParam, actual->lParam);
219  }
220  }
221  else
222  {
223  ok_(file, line) (expected->lParam == actual->lParam,
224  "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
225  context, expected->message, expected->lParam, actual->lParam);
226  if (expected->lParam != actual->lParam) dump++;
227  }
228  }
229 
230  if (expected->flags & custdraw)
231  {
232  if (expected->stage != actual->stage && todo)
233  {
234  todo_wine
235  {
236  failcount++;
237  dump++;
238  ok_(file, line) (FALSE,
239  "%s: in msg 0x%04x expecting cd stage 0x%08x got 0x%08x\n",
240  context, expected->message, expected->stage, actual->stage);
241  }
242  }
243  else
244  {
245  ok_(file, line) (expected->stage == actual->stage,
246  "%s: in msg 0x%04x expecting cd stage 0x%08x got 0x%08x\n",
247  context, expected->message, expected->stage, actual->stage);
248  if (expected->stage != actual->stage) dump++;
249  }
250  }
251 
252  if (expected->flags & id)
253  {
254  if (expected->id != actual->id && expected->flags & optional)
255  {
256  expected++;
257  continue;
258  }
259  if (expected->id != actual->id && todo)
260  {
261  todo_wine
262  {
263  failcount++;
264  dump++;
265  ok_(file, line) (FALSE,
266  "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
267  context, expected->message, expected->id, actual->id);
268  }
269  }
270  else
271  {
272  ok_(file, line) (expected->id == actual->id,
273  "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
274  context, expected->message, expected->id, actual->id);
275  if (expected->id != actual->id) dump++;
276  }
277  }
278 
279  if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo)
280  {
281  todo_wine
282  {
283  failcount++;
284  dump++;
285  ok_(file, line) (FALSE,
286  "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
287  context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
288  }
289  }
290  else
291  {
292  ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc),
293  "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
294  context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
295  if ((expected->flags & defwinproc) != (actual->flags & defwinproc)) dump++;
296  }
297 
298  ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint),
299  "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
300  context, expected->message, (expected->flags & beginpaint) ? "" : "NOT ");
301  if ((expected->flags & beginpaint) != (actual->flags & beginpaint)) dump++;
302 
303  ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
304  "%s: the msg 0x%04x should have been %s\n",
305  context, expected->message, (expected->flags & posted) ? "posted" : "sent");
306  if ((expected->flags & (sent|posted)) != (actual->flags & (sent|posted))) dump++;
307 
308  ok_(file, line) ((expected->flags & parent) == (actual->flags & parent),
309  "%s: the msg 0x%04x was expected in %s\n",
310  context, expected->message, (expected->flags & parent) ? "parent" : "child");
311  if ((expected->flags & parent) != (actual->flags & parent)) dump++;
312 
313  ok_(file, line) ((expected->flags & hook) == (actual->flags & hook),
314  "%s: the msg 0x%04x should have been sent by a hook\n",
315  context, expected->message);
316  if ((expected->flags & hook) != (actual->flags & hook)) dump++;
317 
318  ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook),
319  "%s: the msg 0x%04x should have been sent by a winevent hook\n",
320  context, expected->message);
321  if ((expected->flags & winevent_hook) != (actual->flags & winevent_hook)) dump++;
322 
323  expected++;
324  actual++;
325  }
326  else if (expected->flags & optional)
327  expected++;
328  else if (todo)
329  {
330  failcount++;
331  dump++;
332  todo_wine
333  {
334  ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
335  context, expected->message, actual->message);
336  }
337  goto done;
338  }
339  else
340  {
341  ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
342  context, expected->message, actual->message);
343  dump++;
344  expected++;
345  actual++;
346  }
347  }
348 
349  /* skip all optional trailing messages */
350  while (expected->message && ((expected->flags & optional)))
351  expected++;
352 
353  if (todo)
354  {
355  todo_wine
356  {
357  if (expected->message || actual->message)
358  {
359  failcount++;
360  dump++;
361  ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
362  context, expected->message, actual->message);
363  }
364  }
365  }
366  else if (expected->message || actual->message)
367  {
368  dump++;
369  ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
370  context, expected->message, actual->message);
371  }
372 
373  if(todo && !failcount) /* succeeded yet marked todo */
374  {
375  if (!strcmp(winetest_platform, "wine")) dump++;
376  todo_wine
377  {
378  ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
379  }
380  }
381 
382 done:
383  if (dump) dump_sequence( seq, sequence_index, expected_list, context, file, line );
384  flush_sequence(seq, sequence_index);
385 }
386 
387 #define ok_sequence(seq, index, exp, contx, todo) \
388  ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
389 
390 
391 static inline void init_msg_sequences(struct msg_sequence **seq, int n)
392 {
393  int i;
394 
395  for (i = 0; i < n; i++)
396  seq[i] = heap_alloc_zero(sizeof(*seq[i]));
397 }
UINT message
Definition: msg.h:50
#define trace_(file, line,...)
Definition: kmt_test.h:221
Definition: tftpd.h:59
#define TRUE
Definition: types.h:120
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
Definition: http.c:7098
GLuint GLuint GLsizei count
Definition: gl.h:1545
Definition: msg.h:39
static void dump_sequence(struct msg_sequence **seq, int sequence_index, const struct message *expected, const char *context, const char *file, int line)
Definition: msg.h:105
BOOL todo
Definition: filedlg.c:313
GLdouble n
Definition: glext.h:7729
#define assert(x)
Definition: debug.h:53
UINT_PTR WPARAM
Definition: windef.h:207
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
struct message * sequence
Definition: msg.h:63
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
Definition: msg.h:45
smooth NULL
Definition: ftsmooth.c:416
Definition: msg.h:37
msg_flags_t
Definition: msg.h:32
int size
Definition: msg.h:62
LONG_PTR LPARAM
Definition: windef.h:208
Definition: parser.c:48
const char * winetest_platform
Definition: msg.h:41
Definition: msg.h:42
static void ok_sequence_(struct msg_sequence **seq, int sequence_index, const struct message *expected_list, const char *context, BOOL todo, const char *file, int line)
Definition: msg.h:167
unsigned long DWORD
Definition: ntddk_ex.h:95
Definition: msg.h:36
DWORD stage
Definition: msg.h:56
Definition: msg.h:34
#define todo_wine
Definition: test.h:163
static struct message * sequence
Definition: subclass.c:48
static void flush_sequence(struct msg_sequence **seg, int sequence_index)
Definition: msg.h:89
seg
Definition: i386-dis.c:3857
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
unsigned int UINT
Definition: ndis.h:50
#define msg(x)
Definition: auth_time.c:54
Definition: msg.h:38
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
Definition: msg.h:40
Definition: msg.h:35
int count
Definition: msg.h:61
static void add_message(struct msg_sequence **seq, int sequence_index, const struct message *msg)
Definition: msg.h:66
static void dump(const void *ptr, unsigned len)
Definition: msc.c:102
msg_flags_t flags
Definition: msg.h:51
UINT id
Definition: msg.h:54
BOOL expected
Definition: store.c:2063
#define ok_(x1, x2)
Definition: atltest.h:61
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: fci.c:126