blob: 361ccdbf59887c24c54f76f9b430d24bfb36f7e4 [file] [log] [blame]
Nikolay Sivov537e3822010-03-06 23:53:00 +03001/* 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#include <assert.h>
22#include <windows.h>
23#include "wine/test.h"
24
25/* undocumented SWP flags - from SDK 3.1 */
26#define SWP_NOCLIENTSIZE 0x0800
27#define SWP_NOCLIENTMOVE 0x1000
28
29typedef enum
30{
31 sent = 0x1,
32 posted = 0x2,
33 parent = 0x4,
34 wparam = 0x8,
35 lparam = 0x10,
36 defwinproc = 0x20,
37 beginpaint = 0x40,
38 optional = 0x80,
39 hook = 0x100,
40 winevent_hook =0x200,
41 id = 0x400
42} msg_flags_t;
43
44struct message
45{
46 UINT message; /* the WM_* code */
47 msg_flags_t flags; /* message props */
48 WPARAM wParam; /* expected value of wParam */
49 LPARAM lParam; /* expected value of lParam */
50 UINT id; /* extra message data: id of the window,
51 notify code etc. */
52};
53
54struct msg_sequence
55{
56 int count;
57 int size;
58 struct message *sequence;
59};
60
61static void add_message(struct msg_sequence **seq, int sequence_index,
62 const struct message *msg)
63{
64 struct msg_sequence *msg_seq = seq[sequence_index];
65
66 if (!msg_seq->sequence)
67 {
68 msg_seq->size = 10;
69 msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0,
70 msg_seq->size * sizeof (struct message));
71 }
72
73 if (msg_seq->count == msg_seq->size)
74 {
75 msg_seq->size *= 2;
76 msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0,
77 msg_seq->sequence,
78 msg_seq->size * sizeof (struct message));
79 }
80
81 assert(msg_seq->sequence);
82
83 msg_seq->sequence[msg_seq->count].message = msg->message;
84 msg_seq->sequence[msg_seq->count].flags = msg->flags;
85 msg_seq->sequence[msg_seq->count].wParam = msg->wParam;
86 msg_seq->sequence[msg_seq->count].lParam = msg->lParam;
87 msg_seq->sequence[msg_seq->count].id = msg->id;
88
89 msg_seq->count++;
90}
91
92static void flush_sequence(struct msg_sequence **seg, int sequence_index)
93{
94 struct msg_sequence *msg_seq = seg[sequence_index];
95 HeapFree(GetProcessHeap(), 0, msg_seq->sequence);
96 msg_seq->sequence = NULL;
97 msg_seq->count = msg_seq->size = 0;
98}
99
100static void flush_sequences(struct msg_sequence **seq, int n)
101{
102 int i;
103
104 for (i = 0; i < n; i++)
105 flush_sequence(seq, i);
106}
107
108static void ok_sequence_(struct msg_sequence **seq, int sequence_index,
109 const struct message *expected, const char *context, int todo,
110 const char *file, int line)
111{
112 struct msg_sequence *msg_seq = seq[sequence_index];
113 static const struct message end_of_sequence = {0, 0, 0, 0};
114 const struct message *actual, *sequence;
115 int failcount = 0;
116
117 add_message(seq, sequence_index, &end_of_sequence);
118
119 sequence = msg_seq->sequence;
120 actual = sequence;
121
122 while (expected->message && actual->message)
123 {
124 trace_( file, line)("expected %04x - actual %04x\n", expected->message, actual->message);
125
126 if (expected->message == actual->message)
127 {
128 if (expected->flags & wparam)
129 {
130 if (expected->wParam != actual->wParam && todo)
131 {
132 todo_wine
133 {
134 failcount++;
135 ok_(file, line) (FALSE,
136 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
137 context, expected->message, expected->wParam, actual->wParam);
138 }
139 }
140 else
141 {
142 ok_(file, line) (expected->wParam == actual->wParam,
143 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
144 context, expected->message, expected->wParam, actual->wParam);
145 }
146 }
147
148 if (expected->flags & lparam)
149 {
150 if (expected->lParam != actual->lParam && todo)
151 {
152 todo_wine
153 {
154 failcount++;
155 ok_(file, line) (FALSE,
156 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
157 context, expected->message, expected->lParam, actual->lParam);
158 }
159 }
160 else
161 {
162 ok_(file, line) (expected->lParam == actual->lParam,
163 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
164 context, expected->message, expected->lParam, actual->lParam);
165 }
166 }
167
168 if (expected->flags & id)
169 {
170 if (expected->id != actual->id && expected->flags & optional)
171 {
172 expected++;
173 continue;
174 }
175 if (expected->id != actual->id && todo)
176 {
177 todo_wine
178 {
179 failcount++;
180 ok_(file, line) (FALSE,
181 "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
182 context, expected->message, expected->id, actual->id);
183 }
184 }
185 else
186 {
187 ok_(file, line) (expected->id == actual->id,
188 "%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
189 context, expected->message, expected->id, actual->id);
190 }
191 }
192
193 if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo)
194 {
195 todo_wine
196 {
197 failcount++;
198 ok_(file, line) (FALSE,
199 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
200 context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
201 }
202 }
203 else
204 {
205 ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc),
206 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
207 context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
208 }
209
210 ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint),
211 "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
212 context, expected->message, (expected->flags & beginpaint) ? "" : "NOT ");
213 ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
214 "%s: the msg 0x%04x should have been %s\n",
215 context, expected->message, (expected->flags & posted) ? "posted" : "sent");
216 ok_(file, line) ((expected->flags & parent) == (actual->flags & parent),
217 "%s: the msg 0x%04x was expected in %s\n",
218 context, expected->message, (expected->flags & parent) ? "parent" : "child");
219 ok_(file, line) ((expected->flags & hook) == (actual->flags & hook),
220 "%s: the msg 0x%04x should have been sent by a hook\n",
221 context, expected->message);
222 ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook),
223 "%s: the msg 0x%04x should have been sent by a winevent hook\n",
224 context, expected->message);
225 expected++;
226 actual++;
227 }
228 else if (expected->flags & optional)
229 expected++;
230 else if (todo)
231 {
232 failcount++;
233 todo_wine
234 {
235 ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
236 context, expected->message, actual->message);
237 }
238
239 flush_sequence(seq, sequence_index);
240 return;
241 }
242 else
243 {
244 ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
245 context, expected->message, actual->message);
246 expected++;
247 actual++;
248 }
249 }
250
251 /* skip all optional trailing messages */
252 while (expected->message && ((expected->flags & optional)))
253 expected++;
254
255 if (todo)
256 {
257 todo_wine
258 {
259 if (expected->message || actual->message)
260 {
261 failcount++;
262 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
263 context, expected->message, actual->message);
264 }
265 }
266 }
267 else if (expected->message || actual->message)
268 {
269 ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
270 context, expected->message, actual->message);
271 }
272
273 if(todo && !failcount) /* succeeded yet marked todo */
274 {
275 todo_wine
276 {
277 ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
278 }
279 }
280
281 flush_sequence(seq, sequence_index);
282}
283
284#define ok_sequence(seq, index, exp, contx, todo) \
285 ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
286
287
288static void init_msg_sequences(struct msg_sequence **seq, int n)
289{
290 int i;
291
292 for (i = 0; i < n; i++)
293 seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence));
294}