shell32/tests: Make SHChangeNotify tests more easily extendible.

This commit is contained in:
Andrew Eikum 2010-11-12 15:32:49 -06:00 committed by Alexandre Julliard
parent b1b485e65c
commit 71fad7d18d
1 changed files with 69 additions and 68 deletions

View File

@ -71,6 +71,26 @@ static HRESULT (WINAPI *pSHGetIDListFromObject)(IUnknown*, PIDLIST_ABSOLUTE*);
static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**); static HRESULT (WINAPI *pSHGetItemFromObject)(IUnknown*,REFIID,void**);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
static WCHAR *make_wstr(const char *str)
{
WCHAR *ret;
int len;
if(!str || strlen(str) == 0)
return NULL;
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
if(!len || len < 0)
return NULL;
ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if(!ret)
return NULL;
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
return ret;
}
static int strcmp_wa(LPCWSTR strw, const char *stra) static int strcmp_wa(LPCWSTR strw, const char *stra)
{ {
CHAR buf[512]; CHAR buf[512];
@ -4189,13 +4209,19 @@ static void test_ParseDisplayNamePBC(void)
static const CHAR testwindow_class[] = "testwindow"; static const CHAR testwindow_class[] = "testwindow";
#define WM_USER_NOTIFY (WM_APP+1) #define WM_USER_NOTIFY (WM_APP+1)
static struct { struct ChNotifyTest {
const char *id; const char id[256];
BOOL exp_notify; const UINT notify_count;
UINT missing_events;
UINT signal; UINT signal;
const WCHAR *path_1; const char path_1[256];
const WCHAR *path_2; const char path_2[256];
} exp_data; } chnotify_tests[] = {
{"MKDIR", 1, 0, SHCNE_MKDIR, "C:\\shell32_cn_test\\test", ""},
{"RMDIR", 1, 0, SHCNE_RMDIR, "C:\\shell32_cn_test\\test", ""},
};
struct ChNotifyTest *exp_data;
static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{ {
@ -4203,20 +4229,25 @@ static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, L
switch(msg){ switch(msg){
case WM_USER_NOTIFY: case WM_USER_NOTIFY:
if(exp_data.exp_notify){ if(exp_data->missing_events > 0){
WCHAR *path1, *path2;
LPCITEMIDLIST *pidls = (LPCITEMIDLIST*)wparam; LPCITEMIDLIST *pidls = (LPCITEMIDLIST*)wparam;
ok(exp_data.signal == signal, ok(exp_data->signal == signal,
"%s: expected notification type %x, got: %x\n", "%s: expected notification type %x, got: %x\n",
exp_data.id, exp_data.signal, signal); exp_data->id, exp_data->signal, signal);
trace("verifying pidls for: %s\n", exp_data.id); trace("verifying pidls for: %s\n", exp_data->id);
verify_pidl(pidls[0], exp_data.path_1); path1 = make_wstr(exp_data->path_1);
verify_pidl(pidls[1], exp_data.path_2); path2 = make_wstr(exp_data->path_2);
verify_pidl(pidls[0], path1);
verify_pidl(pidls[1], path2);
HeapFree(GetProcessHeap(), 0, path1);
HeapFree(GetProcessHeap(), 0, path2);
exp_data.exp_notify = FALSE; exp_data->missing_events--;
}else }else
ok(exp_data.exp_notify, "Didn't expect a WM_USER_NOTIFY message (event: %x)\n", signal); ok(0, "Didn't expect a WM_USER_NOTIFY message (event: %x)\n", signal);
return 0; return 0;
} }
return DefWindowProc(hwnd, msg, wparam, lparam); return DefWindowProc(hwnd, msg, wparam, lparam);
@ -4244,37 +4275,31 @@ static void register_testwindow_class(void)
static void do_events(void) static void do_events(void)
{ {
int c = 0; int c = 0;
while (exp_data.exp_notify && (c++ < 10)){ while (exp_data->missing_events && (c++ < 10)){
MSG msg; MSG msg;
while(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)){ while(PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessageA(&msg); DispatchMessageA(&msg);
} }
if(exp_data.exp_notify) if(exp_data->missing_events)
Sleep(500); Sleep(500);
} }
trace("%s: took %d tries\n", exp_data.id, c); trace("%s: took %d tries\n", exp_data->id, c);
} }
static void test_SHChangeNotify(void) static void test_SHChangeNotify(void)
{ {
HWND wnd; HWND wnd;
ULONG notifyID; ULONG notifyID, i;
HRESULT hr; HRESULT hr;
BOOL br, has_unicode; BOOL br, has_unicode;
SHChangeNotifyEntry entries[1]; SHChangeNotifyEntry entries[1];
const CHAR root_dirA[] = "C:\\shell32_cn_test"; const CHAR root_dirA[] = "C:\\shell32_cn_test";
const WCHAR root_dirW[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t',0}; const WCHAR root_dirW[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t',0};
const CHAR test_dirA[] = "C:\\shell32_cn_test\\test";
const WCHAR test_dirW[] = {'C',':','\\','s','h','e','l','l','3','2','_','c','n','_','t','e','s','t','\\','t','e','s','t',0};
CreateDirectoryW(NULL, NULL); CreateDirectoryW(NULL, NULL);
has_unicode = !(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED); has_unicode = !(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
/* set up the root directory & window */
br = CreateDirectoryA(root_dirA, NULL);
ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
register_testwindow_class(); register_testwindow_class();
wnd = CreateWindowExA(0, testwindow_class, testwindow_class, 0, wnd = CreateWindowExA(0, testwindow_class, testwindow_class, 0,
@ -4282,6 +4307,9 @@ static void test_SHChangeNotify(void)
NULL, NULL, GetModuleHandleA(NULL), 0); NULL, NULL, GetModuleHandleA(NULL), 0);
ok(wnd != NULL, "Failed to make a window\n"); ok(wnd != NULL, "Failed to make a window\n");
br = CreateDirectoryA(root_dirA, NULL);
ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
entries[0].pidl = NULL; entries[0].pidl = NULL;
if(has_unicode) if(has_unicode)
hr = SHILCreateFromPath(root_dirW, (LPITEMIDLIST*)&entries[0].pidl, 0); hr = SHILCreateFromPath(root_dirW, (LPITEMIDLIST*)&entries[0].pidl, 0);
@ -4294,55 +4322,28 @@ static void test_SHChangeNotify(void)
SHCNE_ALLEVENTS, WM_USER_NOTIFY, 1, entries); SHCNE_ALLEVENTS, WM_USER_NOTIFY, 1, entries);
ok(notifyID != 0, "Failed to register a window for change notifications\n"); ok(notifyID != 0, "Failed to register a window for change notifications\n");
/* MKDIR */ for(i = 0; i < sizeof(chnotify_tests) / sizeof(*chnotify_tests); ++i){
br = CreateDirectoryA(test_dirA, NULL); exp_data = chnotify_tests + i;
ok(br == TRUE, "CreateDirectory failed: %d\n", GetLastError());
if(has_unicode){ exp_data->missing_events = exp_data->notify_count;
exp_data.id = "MKDIR PATHW"; SHChangeNotify(exp_data->signal, SHCNF_PATHA | SHCNF_FLUSH,
exp_data.signal = SHCNE_MKDIR; strlen(exp_data->path_1) > 0 ? exp_data->path_1 : NULL,
exp_data.exp_notify = TRUE; strlen(exp_data->path_2) > 0 ? exp_data->path_2 : NULL);
exp_data.path_1 = test_dirW;
exp_data.path_2 = NULL;
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHW | SHCNF_FLUSH, test_dirW, NULL);
do_events(); do_events();
ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n"); ok(exp_data->missing_events == 0, "%s: Expected wndproc to be called\n", exp_data->id);
}else
win_skip("skipping WCHAR tests\n");
exp_data.id = "MKDIR PATHA"; if(has_unicode){
exp_data.signal = SHCNE_MKDIR; WCHAR *path1, *path2;
exp_data.exp_notify = TRUE;
exp_data.path_1 = test_dirW;
exp_data.path_2 = NULL;
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATHA | SHCNF_FLUSH, test_dirA, NULL);
do_events();
ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
/* RMDIR */ path1 = make_wstr(exp_data->path_1);
br = RemoveDirectoryA(test_dirA); path2 = make_wstr(exp_data->path_2);
ok(br == TRUE, "RemoveDirectory failed: %d\n", GetLastError());
if(has_unicode){ exp_data->missing_events = exp_data->notify_count;
exp_data.id = "RMDIR PATHW"; SHChangeNotify(exp_data->signal, SHCNF_PATHW | SHCNF_FLUSH, path1, path2);
exp_data.signal = SHCNE_RMDIR; do_events();
exp_data.exp_notify = TRUE; ok(exp_data->missing_events == 0, "%s: Expected wndproc to be called\n", exp_data->id);
exp_data.path_1 = test_dirW; }
exp_data.path_2 = NULL; }
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHW | SHCNF_FLUSH, test_dirW, NULL);
do_events();
ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
}else
win_skip("skipping WCHAR tests\n");
exp_data.id = "RMDIR PATHA";
exp_data.signal = SHCNE_RMDIR;
exp_data.exp_notify = TRUE;
exp_data.path_1 = test_dirW;
exp_data.path_2 = NULL;
SHChangeNotify(SHCNE_RMDIR, SHCNF_PATHA | SHCNF_FLUSH, test_dirA, NULL);
do_events();
ok(exp_data.exp_notify == FALSE, "Expected wndproc to be called\n");
SHChangeNotifyDeregister(notifyID); SHChangeNotifyDeregister(notifyID);
DestroyWindow(wnd); DestroyWindow(wnd);