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 void add_message(struct msg_sequence
**seq
, int sequence_index
,
65 const struct message
*msg
)
67 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
69 if (!msg_seq
->sequence
)
72 msg_seq
->sequence
= heap_alloc(msg_seq
->size
* sizeof (*msg_seq
->sequence
));
75 if (msg_seq
->count
== msg_seq
->size
)
78 msg_seq
->sequence
= heap_realloc(msg_seq
->sequence
, msg_seq
->size
* sizeof (*msg_seq
->sequence
));
81 assert(msg_seq
->sequence
);
83 msg_seq
->sequence
[msg_seq
->count
] = *msg
;
87 static inline void flush_sequence(struct msg_sequence
**seg
, int sequence_index
)
89 struct msg_sequence
*msg_seq
= seg
[sequence_index
];
90 heap_free(msg_seq
->sequence
);
91 msg_seq
->sequence
= NULL
;
92 msg_seq
->count
= msg_seq
->size
= 0;
95 static inline void flush_sequences(struct msg_sequence
**seq
, int n
)
99 for (i
= 0; i
< n
; i
++)
100 flush_sequence(seq
, i
);
103 static void dump_sequence( struct msg_sequence
**seq
, int sequence_index
,
104 const struct message
*expected
, const char *context
,
105 const char *file
, int line
)
107 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
108 const struct message
*actual
, *sequence
;
109 unsigned int count
= 0;
111 sequence
= msg_seq
->sequence
;
114 trace_(file
, line
)("Failed sequence %s:\n", context
);
115 while (expected
->message
&& actual
->message
)
117 trace_(file
, line
)( " %u: expected: %04x - actual: %04x wp %08lx lp %08lx\n",
118 count
, expected
->message
, actual
->message
, actual
->wParam
, actual
->lParam
);
120 if (expected
->message
== actual
->message
)
122 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) &&
123 (expected
->flags
& optional
))
125 /* don't match messages if their defwinproc status differs */
142 /* optional trailing messages */
143 while (expected
->message
&& expected
->flags
& optional
)
145 trace_(file
, line
)( " %u: expected: msg %04x - actual: nothing\n", count
, expected
->message
);
150 if (expected
->message
)
152 trace_(file
, line
)( " %u: expected: msg %04x - actual: nothing\n", count
, expected
->message
);
156 while (actual
->message
)
158 trace_(file
, line
)( " %u: expected: nothing - actual: %04x wp %08lx lp %08lx\n",
159 count
, actual
->message
, actual
->wParam
, actual
->lParam
);
165 static void ok_sequence_(struct msg_sequence
**seq
, int sequence_index
,
166 const struct message
*expected_list
, const char *context
, BOOL todo
,
167 const char *file
, int line
)
169 static const struct message end_of_sequence
= {0, 0, 0, 0};
170 struct msg_sequence
*msg_seq
= seq
[sequence_index
];
171 const struct message
*expected
= expected_list
;
172 const struct message
*actual
, *sequence
;
173 int failcount
= 0, dump
= 0;
175 add_message(seq
, sequence_index
, &end_of_sequence
);
177 sequence
= msg_seq
->sequence
;
180 while (expected
->message
&& actual
->message
)
182 if (expected
->message
== actual
->message
)
184 if (expected
->flags
& wparam
)
186 if (expected
->wParam
!= actual
->wParam
&& todo
)
192 ok_(file
, line
) (FALSE
,
193 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
194 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
199 ok_(file
, line
) (expected
->wParam
== actual
->wParam
,
200 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
201 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
202 if (expected
->wParam
!= actual
->wParam
) dump
++;
206 if (expected
->flags
& lparam
)
208 if (expected
->lParam
!= actual
->lParam
&& todo
)
214 ok_(file
, line
) (FALSE
,
215 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
216 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
221 ok_(file
, line
) (expected
->lParam
== actual
->lParam
,
222 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
223 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
224 if (expected
->lParam
!= actual
->lParam
) dump
++;
228 if (expected
->flags
& custdraw
)
230 if (expected
->stage
!= actual
->stage
&& todo
)
236 ok_(file
, line
) (FALSE
,
237 "%s: in msg 0x%04x expecting cd stage 0x%08x got 0x%08x\n",
238 context
, expected
->message
, expected
->stage
, actual
->stage
);
243 ok_(file
, line
) (expected
->stage
== actual
->stage
,
244 "%s: in msg 0x%04x expecting cd stage 0x%08x got 0x%08x\n",
245 context
, expected
->message
, expected
->stage
, actual
->stage
);
246 if (expected
->stage
!= actual
->stage
) dump
++;
250 if (expected
->flags
& id
)
252 if (expected
->id
!= actual
->id
&& expected
->flags
& optional
)
257 if (expected
->id
!= actual
->id
&& todo
)
263 ok_(file
, line
) (FALSE
,
264 "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
265 context
, expected
->message
, expected
->id
, actual
->id
);
270 ok_(file
, line
) (expected
->id
== actual
->id
,
271 "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
272 context
, expected
->message
, expected
->id
, actual
->id
);
273 if (expected
->id
!= actual
->id
) dump
++;
277 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) && todo
)
283 ok_(file
, line
) (FALSE
,
284 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
285 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
290 ok_(file
, line
) ((expected
->flags
& defwinproc
) == (actual
->flags
& defwinproc
),
291 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
292 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
293 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
)) dump
++;
296 ok_(file
, line
) ((expected
->flags
& beginpaint
) == (actual
->flags
& beginpaint
),
297 "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
298 context
, expected
->message
, (expected
->flags
& beginpaint
) ? "" : "NOT ");
299 if ((expected
->flags
& beginpaint
) != (actual
->flags
& beginpaint
)) dump
++;
301 ok_(file
, line
) ((expected
->flags
& (sent
|posted
)) == (actual
->flags
& (sent
|posted
)),
302 "%s: the msg 0x%04x should have been %s\n",
303 context
, expected
->message
, (expected
->flags
& posted
) ? "posted" : "sent");
304 if ((expected
->flags
& (sent
|posted
)) != (actual
->flags
& (sent
|posted
))) dump
++;
306 ok_(file
, line
) ((expected
->flags
& parent
) == (actual
->flags
& parent
),
307 "%s: the msg 0x%04x was expected in %s\n",
308 context
, expected
->message
, (expected
->flags
& parent
) ? "parent" : "child");
309 if ((expected
->flags
& parent
) != (actual
->flags
& parent
)) dump
++;
311 ok_(file
, line
) ((expected
->flags
& hook
) == (actual
->flags
& hook
),
312 "%s: the msg 0x%04x should have been sent by a hook\n",
313 context
, expected
->message
);
314 if ((expected
->flags
& hook
) != (actual
->flags
& hook
)) dump
++;
316 ok_(file
, line
) ((expected
->flags
& winevent_hook
) == (actual
->flags
& winevent_hook
),
317 "%s: the msg 0x%04x should have been sent by a winevent hook\n",
318 context
, expected
->message
);
319 if ((expected
->flags
& winevent_hook
) != (actual
->flags
& winevent_hook
)) dump
++;
324 else if (expected
->flags
& optional
)
332 ok_(file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
333 context
, expected
->message
, actual
->message
);
339 ok_(file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
340 context
, expected
->message
, actual
->message
);
347 /* skip all optional trailing messages */
348 while (expected
->message
&& ((expected
->flags
& optional
)))
355 if (expected
->message
|| actual
->message
)
359 ok_(file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
360 context
, expected
->message
, actual
->message
);
364 else if (expected
->message
|| actual
->message
)
367 ok_(file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
368 context
, expected
->message
, actual
->message
);
371 if(todo
&& !failcount
) /* succeeded yet marked todo */
373 if (!strcmp(winetest_platform
, "wine")) dump
++;
376 ok_(file
, line
)(TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
381 if (dump
) dump_sequence( seq
, sequence_index
, expected_list
, context
, file
, line
);
382 flush_sequence(seq
, sequence_index
);
385 #define ok_sequence(seq, index, exp, contx, todo) \
386 ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
389 static void init_msg_sequences(struct msg_sequence
**seq
, int n
)
393 for (i
= 0; i
< n
; i
++)
394 seq
[i
] = heap_alloc_zero(sizeof(*seq
[i
]));