1 /* Message Sequence Testing Code
3 * Copyright (C) 2007 James Hawkins
4 * Copyright (C) 2007 Lei Zhang
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.
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.
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
23 #include "wine/heap.h"
24 #include "wine/test.h"
26 /* undocumented SWP flags - from SDK 3.1 */
27 #define SWP_NOCLIENTSIZE 0x0800
28 #define SWP_NOCLIENTMOVE 0x1000
48 UINT message
; /* the WM_* code */
49 msg_flags_t flags
; /* message props */
50 WPARAM wParam
; /* expected value of wParam */
51 LPARAM lParam
; /* expected value of lParam */
52 UINT id
; /* extra message data: id of the window,
54 DWORD stage
; /* custom draw stage */
61 struct message
*sequence
;
64 static HWINEVENTHOOK hwineventhook
;
66 static void add_message(struct msg_sequence
**seq
, int sequence_index
,
67 const struct message
*msg
)
69 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
71 if (!msg_seq
->sequence
)
74 msg_seq
->sequence
= malloc(msg_seq
->size
* sizeof (*msg_seq
->sequence
));
77 if (msg_seq
->count
== msg_seq
->size
)
80 msg_seq
->sequence
= realloc(msg_seq
->sequence
, msg_seq
->size
* sizeof (*msg_seq
->sequence
));
83 assert(msg_seq
->sequence
);
85 msg_seq
->sequence
[msg_seq
->count
] = *msg
;
89 static inline void flush_sequence(struct msg_sequence
**seg
, int sequence_index
)
91 struct msg_sequence
*msg_seq
= seg
[sequence_index
];
92 free(msg_seq
->sequence
);
93 msg_seq
->sequence
= NULL
;
94 msg_seq
->count
= msg_seq
->size
= 0;
97 static inline void flush_sequences(struct msg_sequence
**seq
, int n
)
101 for (i
= 0; i
< n
; i
++)
102 flush_sequence(seq
, i
);
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
)
109 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
110 const struct message
*actual
, *sequence
;
111 unsigned int count
= 0;
113 sequence
= msg_seq
->sequence
;
116 trace_(file
, line
)("Failed sequence %s:\n", context
);
117 while (expected
->message
&& actual
->message
)
119 trace_(file
, line
)( " %u: expected: %04x - actual: %04x wp %08Ix lp %08Ix\n",
120 count
, expected
->message
, actual
->message
, actual
->wParam
, actual
->lParam
);
122 if (expected
->message
== actual
->message
)
124 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) &&
125 ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hwineventhook
)))
127 /* don't match messages if their defwinproc status differs */
144 /* optional trailing messages */
145 while (expected
->message
&& (expected
->flags
& optional
||
146 ((expected
->flags
& winevent_hook
) && !hwineventhook
)))
148 trace_(file
, line
)( " %u: expected: msg %04x - actual: nothing\n", count
, expected
->message
);
153 if (expected
->message
)
155 trace_(file
, line
)( " %u: expected: msg %04x - actual: nothing\n", count
, expected
->message
);
159 while (actual
->message
)
161 trace_(file
, line
)( " %u: expected: nothing - actual: %04x wp %08Ix lp %08Ix\n",
162 count
, actual
->message
, actual
->wParam
, actual
->lParam
);
168 static void ok_sequence_(struct msg_sequence
**seq
, int sequence_index
,
169 const struct message
*expected_list
, const char *context
, BOOL todo
,
170 const char *file
, int line
)
172 static const struct message end_of_sequence
= {0, 0, 0, 0};
173 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
174 const struct message
*expected
= expected_list
;
175 const struct message
*actual
, *sequence
;
176 int failcount
= 0, dump
= 0;
178 add_message(seq
, sequence_index
, &end_of_sequence
);
180 sequence
= msg_seq
->sequence
;
183 while (expected
->message
&& actual
->message
)
185 if (expected
->message
== actual
->message
)
187 if (expected
->flags
& wparam
)
189 if (expected
->wParam
!= actual
->wParam
&& todo
)
195 ok_(file
, line
) (FALSE
,
196 "%s: in msg 0x%04x expecting wParam 0x%Ix got 0x%Ix\n",
197 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
202 ok_(file
, line
) (expected
->wParam
== actual
->wParam
,
203 "%s: in msg 0x%04x expecting wParam 0x%Ix got 0x%Ix\n",
204 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
205 if (expected
->wParam
!= actual
->wParam
) dump
++;
209 if (expected
->flags
& lparam
)
211 if (expected
->lParam
!= actual
->lParam
&& todo
)
217 ok_(file
, line
) (FALSE
,
218 "%s: in msg 0x%04x expecting lParam 0x%Ix got 0x%Ix\n",
219 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
224 ok_(file
, line
) (expected
->lParam
== actual
->lParam
,
225 "%s: in msg 0x%04x expecting lParam 0x%Ix got 0x%Ix\n",
226 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
227 if (expected
->lParam
!= actual
->lParam
) dump
++;
231 if (expected
->flags
& custdraw
)
233 if (expected
->stage
!= actual
->stage
&& todo
)
239 ok_(file
, line
) (FALSE
,
240 "%s: in msg 0x%04x expecting cd stage 0x%08lx got 0x%08lx\n",
241 context
, expected
->message
, expected
->stage
, actual
->stage
);
246 ok_(file
, line
) (expected
->stage
== actual
->stage
,
247 "%s: in msg 0x%04x expecting cd stage 0x%08lx got 0x%08lx\n",
248 context
, expected
->message
, expected
->stage
, actual
->stage
);
249 if (expected
->stage
!= actual
->stage
) dump
++;
253 if (expected
->flags
& id
)
255 if (expected
->id
!= actual
->id
&& ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hwineventhook
)))
260 if (expected
->id
!= actual
->id
&& todo
)
266 ok_(file
, line
) (FALSE
,
267 "%s: in msg 0x%04x expecting id %d got %d\n",
268 context
, expected
->message
, expected
->id
, actual
->id
);
273 ok_(file
, line
) (expected
->id
== actual
->id
,
274 "%s: in msg 0x%04x expecting id %d got %d\n",
275 context
, expected
->message
, expected
->id
, actual
->id
);
276 if (expected
->id
!= actual
->id
) dump
++;
280 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) && todo
)
286 ok_(file
, line
) (FALSE
,
287 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
288 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
293 ok_(file
, line
) ((expected
->flags
& defwinproc
) == (actual
->flags
& defwinproc
),
294 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
295 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
296 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
)) dump
++;
299 ok_(file
, line
) ((expected
->flags
& beginpaint
) == (actual
->flags
& beginpaint
),
300 "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
301 context
, expected
->message
, (expected
->flags
& beginpaint
) ? "" : "NOT ");
302 if ((expected
->flags
& beginpaint
) != (actual
->flags
& beginpaint
)) dump
++;
304 ok_(file
, line
) ((expected
->flags
& (sent
|posted
)) == (actual
->flags
& (sent
|posted
)),
305 "%s: the msg 0x%04x should have been %s\n",
306 context
, expected
->message
, (expected
->flags
& posted
) ? "posted" : "sent");
307 if ((expected
->flags
& (sent
|posted
)) != (actual
->flags
& (sent
|posted
))) dump
++;
309 ok_(file
, line
) ((expected
->flags
& parent
) == (actual
->flags
& parent
),
310 "%s: the msg 0x%04x was expected in %s\n",
311 context
, expected
->message
, (expected
->flags
& parent
) ? "parent" : "child");
312 if ((expected
->flags
& parent
) != (actual
->flags
& parent
)) dump
++;
314 ok_(file
, line
) ((expected
->flags
& hook
) == (actual
->flags
& hook
),
315 "%s: the msg 0x%04x should have been sent by a hook\n",
316 context
, expected
->message
);
317 if ((expected
->flags
& hook
) != (actual
->flags
& hook
)) dump
++;
319 ok_(file
, line
) ((expected
->flags
& winevent_hook
) == (actual
->flags
& winevent_hook
),
320 "%s: the msg 0x%04x should have been sent by a winevent hook\n",
321 context
, expected
->message
);
322 if ((expected
->flags
& winevent_hook
) != (actual
->flags
& winevent_hook
)) dump
++;
327 else if ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hwineventhook
))
335 ok_(file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
336 context
, expected
->message
, actual
->message
);
342 ok_(file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
343 context
, expected
->message
, actual
->message
);
350 /* skip all optional trailing messages */
351 while (expected
->message
&& ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hwineventhook
)))
358 if (expected
->message
|| actual
->message
)
362 ok_(file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
363 context
, expected
->message
, actual
->message
);
367 else if (expected
->message
|| actual
->message
)
370 ok_(file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
371 context
, expected
->message
, actual
->message
);
374 if(todo
&& !failcount
) /* succeeded yet marked todo */
376 if (!strcmp(winetest_platform
, "wine")) dump
++;
379 ok_(file
, line
)(TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
384 if (dump
) dump_sequence( seq
, sequence_index
, expected_list
, context
, file
, line
);
385 flush_sequence(seq
, sequence_index
);
388 #define ok_sequence(seq, index, exp, contx, todo) \
389 ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
392 static void init_msg_sequences(struct msg_sequence
**seq
, int n
)
396 for (i
= 0; i
< n
; i
++)
397 seq
[i
] = calloc(1, sizeof(*seq
[i
]));